home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 411b.lha / dme_1.42 / src.LZH / src / cmd1.c < prev    next >
C/C++ Source or Header  |  1990-04-23  |  19KB  |  1,079 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 <libraries/dos.h>
  10. #include <libraries/dosextens.h>
  11.  
  12. typedef struct Process PROC;
  13.  
  14. #define nomemory()  { memoryfail = 1; }
  15.  
  16. char RecallBuf[256];
  17.  
  18. void
  19. setpen(line)
  20. {
  21.     ED *ep = Ep;
  22.     RP *rp = ep->Win->RPort;
  23.  
  24.     short pen = (ep == BEp && line >= BSline && line <= BEline) ? ep->HGPen : ep->FGPen;
  25.     if (Comlinemode)
  26.     pen = ep->FGPen;
  27.     if (pen != rp->FgPen)
  28.     SetAPen(rp, pen);
  29. }
  30.  
  31. text_init(oldep, win, nw)
  32. ED *oldep;
  33. WIN *win;
  34. struct NewWindow *nw;
  35. {
  36.     ED *e;
  37.  
  38.     text_switch(NULL);
  39.     e = (ED *)allocb(sizeof(ED));
  40.     if (e == NULL)
  41.     return(0);
  42.     setmem(e, sizeof(ED), 0);
  43.     e->Win = win;
  44.     if (oldep) {
  45.     e->dirlock = (long)DupLock((BPTR)oldep->dirlock);
  46.  
  47.     movmem(&oldep->BeginConfig, &e->BeginConfig, (char *)&e->EndConfig - (char *)&e->BeginConfig);
  48.  
  49.     if (oldep->Font) {
  50.         e->Font = oldep->Font;
  51.         ++e->Font->tf_Accessors;
  52.         if (win)
  53.         SetFont(win->RPort, e->Font);
  54.     }
  55.     e->IWiny = 16;
  56.     } else {
  57.     PROC *proc = (PROC *)FindTask(NULL);
  58.     e->dirlock = (long)DupLock((BPTR)proc->pr_CurrentDir);
  59.  
  60.     e->Insertmode = 1;
  61.     e->Tabstop = 4;
  62.     e->WWCol = -1;
  63.     e->Margin= 75;
  64.     e->FGPen = 1;
  65.     e->BGPen = 0;
  66.     e->HGPen = 2;
  67.     loadconfig(e);
  68.     }
  69.     e->Lines = 1;
  70.     e->Maxlines = 32;
  71.     e->List = (ubyte **)allocl(e->Maxlines);
  72.     e->List[0] = allocb(1);
  73.     e->List[0][0] = Current[0] = Clen = 0;
  74.     AddHead((LIST *)&DBase, (NODE *)e);
  75.     strcpy(e->Name, "unnamed");
  76.     Ep = e;
  77.  
  78.     if (nw) {
  79.     if (e->Winwidth && e->Winheight) {
  80.         nw->LeftEdge= e->Winx;
  81.         nw->TopEdge = e->Winy;
  82.         nw->Width    = e->Winwidth;
  83.         nw->Height    = e->Winheight;
  84.     } else {
  85.         nw->LeftEdge= 0;
  86.         nw->TopEdge = 0;
  87.         nw->Width    = 640;
  88.         nw->Height    = 200;
  89.     }
  90.     nw->DetailPen = e->BGPen;
  91.     nw->BlockPen  = e->FGPen;
  92.     }
  93.  
  94.     return(1);
  95. }
  96.  
  97. text_switch(win)
  98. WIN *win;
  99. {
  100.     ED *e;
  101.  
  102.     if (win)
  103.     text_sync();
  104.     if (win) {
  105.     for (e = (ED *)DBase.mlh_Head; e->Node.mln_Succ; e = (ED *)e->Node.mln_Succ) {
  106.         if (e->Win == win) {
  107.         Ep = e;
  108.         text_load();
  109.         if (!Ep->iconmode) {
  110.             set_window_params();
  111.             window_title();
  112.         }
  113.         return(1);
  114.         }
  115.     }
  116.     return(0);
  117.     }
  118. }
  119.  
  120.  
  121. text_sync()
  122. {
  123.     ED *ep = Ep;
  124.     char redraw = 0;
  125.     short len;
  126.     ubyte *ptr;
  127.  
  128.     for (len = strlen(Current) - 1; len >= 0 && Current[len] == ' '; --len)
  129.     Current[len] = '\0';
  130.     Clen = len + 1;
  131.     if (!Comlinemode) {
  132.     if (strlen(ep->List[ep->Line]) != Clen) {
  133.         if (ptr = allocb(Clen+1)) {
  134.         ep->Modified = 1;
  135.         Overide = 0;
  136.         FreeMem(ep->List[ep->Line], strlen(ep->List[ep->Line])+1);
  137.         ep->List[ep->Line] = ptr;
  138.         } else {
  139.         nomemory();
  140.         strcpy(Current, ep->List[ep->Line]);
  141.         Clen = strlen(Current);
  142.         }
  143.     } else {
  144.         if (strcmp(ep->List[ep->Line], Current)) {
  145.         ep->Modified = 1;
  146.         Overide = 0;
  147.         }
  148.     }
  149.     strcpy(ep->List[ep->Line], Current);
  150.     }
  151.     if (Nsu == 0) {
  152.     if (ep->Column - ep->Topcolumn >= Columns || ep->Column < ep->Topcolumn) {
  153.         redraw = 1;
  154.         ep->Topcolumn = ep->Column - (Columns>>1);
  155.         if (ep->Topcolumn < 0)
  156.         ep->Topcolumn = 0;
  157.     }
  158.     if (ep->Line - ep->Topline >= Rows || ep->Line < ep->Topline) {
  159.         redraw = 1;
  160.         ep->Topline = ep->Line - (Rows>>1);
  161.         if (ep->Topline < 0)
  162.         ep->Topline = 0;
  163.     }
  164.     }
  165.     while (ep->Column > Clen)
  166.     Current[Clen++] = ' ';
  167.     Current[Clen] = '\0';
  168.     if (redraw)
  169.     text_redisplay();
  170.     return((int)redraw);
  171. }
  172.  
  173. text_load()
  174. {
  175.     if (Comlinemode)
  176.     return(0);
  177.     strcpy(Current, Ep->List[Ep->Line]);
  178.     Clen = strlen(Current);
  179.     while (Ep->Column > Clen)
  180.     Current[Clen++] = ' ';
  181.     Current[Clen] = '\0';
  182. }
  183.  
  184. text_colno()
  185. {
  186.     return(Ep->Column);
  187. }
  188.  
  189. text_lineno()
  190. {
  191.     return(Ep->Line+1);
  192. }
  193.  
  194. text_lines()
  195. {
  196.     return(Ep->Lines);
  197. }
  198.  
  199. text_cols()
  200. {
  201.     return((int)Clen);
  202. }
  203.  
  204. text_imode()
  205. {
  206.     return((int)Ep->Insertmode);
  207. }
  208.  
  209. text_tabsize()
  210. {
  211.     return((int)Ep->Tabstop);
  212. }
  213.  
  214. ubyte *
  215. text_name()
  216. {
  217.     return(Ep->Name);
  218. }
  219.  
  220. void
  221. text_uninit()
  222. {
  223.     ED *ep = Ep;
  224.  
  225.     PMKill(ep);
  226.     freelist(ep->List, ep->Lines);
  227.     FreeMem(ep->List, ep->Maxlines * sizeof(char *));
  228.  
  229.     if (BEp == ep) {
  230.     BEp = NULL;
  231.     BSline = BEline = -1;
  232.     }
  233.     Remove((NODE *)ep);
  234.     if (ep->Font) {
  235.     SetFont(ep->Win->RPort, ep->Win->WScreen->RastPort.Font);
  236.     CloseFont(ep->Font);
  237.     }
  238.     UnLock((BPTR)ep->dirlock);
  239.     FreeMem(ep, sizeof(ED));
  240.     if (((ED *)DBase.mlh_Head)->Node.mln_Succ) {
  241.     Ep = (ED *)DBase.mlh_Head;
  242.     text_load();
  243.     } else {
  244.     Ep = NULL;
  245.     }
  246. }
  247.  
  248. void
  249. inversemode(n)
  250. {
  251.     RP *rp = Ep->Win->RPort;
  252.  
  253.     if (n) {
  254.     SetAPen(rp, ~Ep->BGPen);
  255.     SetDrMd(rp, JAM2|INVERSVID);
  256.     } else {
  257.     setpen(Ep->Line);
  258.     SetDrMd(rp, JAM2);
  259.     }
  260. }
  261.  
  262. void
  263. text_cursor(n)
  264. {
  265.     ED *ep = Ep;
  266.     RP *rp = ep->Win->RPort;
  267.  
  268.     movetocursor();
  269.     inversemode(n);
  270.     if (Current[ep->Column])
  271.     Text(rp, Current+ep->Column, 1);
  272.     else
  273.     Text(rp, " ", 1);
  274.     inversemode(0);
  275. }
  276.  
  277. void
  278. text_position(col, row)
  279. {
  280.     ED *ep = Ep;
  281.     text_sync();
  282.     if (col == 0)
  283.     col = -1;
  284.     ep->Column = ep->Topcolumn + col;
  285.     if (ep->Column > 254)
  286.     ep->Column = 254;
  287.     if (ep->Column < 0)
  288.     ep->Column = 0;
  289.     ep->Line = ep->Topline + row;
  290.     if (ep->Line >= ep->Lines)
  291.     ep->Line = ep->Lines - 1;
  292.     if (ep->Line < 0)
  293.     ep->Line = 0;
  294.     text_load();
  295.     text_sync();
  296. }
  297.  
  298. void
  299. displayblock(on)
  300. {
  301.     long start = Ep->Topline;
  302.     long lines = BEline - BSline + 1;
  303.  
  304.     if (start < BSline)
  305.     start = BSline;
  306.     if (!on) {
  307.     BSline = BEline = -1;
  308.     BEp = NULL;
  309.     }
  310.     if (Ep == BEp)
  311.     text_displayseg(start - Ep->Topline, lines);
  312. }
  313.  
  314. void
  315. text_redrawblock(ok)
  316. {
  317.     WIN *savewin = NULL;
  318.  
  319.     if (BEp) {
  320.     if (BEp != Ep) {
  321.         savewin = Ep->Win;
  322.         text_switch(BEp->Win);
  323.     }
  324.     if (BSline <= BEline && BSline >= 0 && BEline < Ep->Lines) {
  325.         if (!ok) {
  326.         BEp = NULL;
  327.         BSline = BEline = -1;
  328.         }
  329.         text_displayseg(0, Rows);
  330.     }
  331.     if (savewin)
  332.         text_switch(savewin);
  333.     }
  334.     if (!ok) {
  335.     BEp = NULL;
  336.     BSline = BEline = -1;
  337.     }
  338. }
  339.  
  340. void
  341. text_displayseg(start, n)
  342. {
  343.     short i, c;
  344.     ubyte *ptr;
  345.     ED *ep = Ep;
  346.     RP *rp = ep->Win->RPort;
  347.  
  348.     if (Nsu)
  349.     return;
  350.     for (i = start; i < start + n && i < Rows && ep->Topline + i < ep->Lines; ++i) {
  351.     if (Comlinemode) {
  352.         if (ep->Topline + i != ep->Line)
  353.         continue;
  354.         ptr = Current;
  355.         SetAPen(rp, ep->FGPen);
  356.     } else {
  357.         ptr = ep->List[ep->Topline + i];
  358.         setpen(i+ep->Topline);
  359.     }
  360.     for (c = ep->Topcolumn; c && *ptr; ++ptr, --c);
  361.     c = strlen(ptr);
  362.     if (c) {
  363.         Move(rp, COLT(0), ROWT(i));
  364.         Text(rp, ptr, (c > Columns) ? Columns : c);
  365.     }
  366.     }
  367. }
  368.  
  369. void
  370. text_redisplay()
  371. {
  372.     ED *ep = Ep;
  373.     RP *rp = ep->Win->RPort;
  374.  
  375.     if (Nsu)
  376.     return;
  377.     SetAPen(rp, ep->BGPen);
  378.     if (Comlinemode)
  379.     RectFill(rp, COL(0), ROW(Rows-1), Xbase + Xpixs - 1, Ybase + Ypixs - 1);
  380.     else
  381.     RectFill(rp, Xbase, Ybase, Xbase + Xpixs - 1, Ybase + Ypixs - 1);
  382.     text_displayseg(0,Rows);
  383. }
  384.  
  385. void
  386. text_redisplaycurrline()
  387. {
  388.     ED *ep = Ep;
  389.     RP *rp = ep->Win->RPort;
  390.  
  391.     int row = ep->Line - ep->Topline;
  392.  
  393.     if (Nsu)
  394.     return;
  395.     SetAPen(rp, ep->BGPen);
  396.     RectFill(rp, COL(0), ROW(row), Xbase + Xpixs - 1, ROW(row+1)-1);
  397.     text_displayseg(row, 1);
  398. }
  399.  
  400. void
  401. text_write(str)
  402. ubyte *str;
  403. {
  404.     short len = strlen(str);
  405.     short i;
  406.     ED *ep = Ep;
  407.     RP *rp = ep->Win->RPort;
  408.  
  409.     if (Clen + len >= 255) {
  410.     text_sync();
  411.     text_load();
  412.     }
  413.     if (ep->Insertmode == 0) {
  414.     if (ep->Column + len >= 255)
  415.         goto fail;
  416.     movmem(str, Current + ep->Column, len);
  417.     if (ep->Column + len >= Clen)
  418.         Clen = ep->Column + len;
  419.     Current[Clen] = 0;
  420.     } else {
  421.     if (Clen + len >= 255)
  422.         goto fail;
  423.     movmem(Current + ep->Column, Current + ep->Column + len, Clen+1-ep->Column);
  424.     movmem(str, Current + ep->Column, len);
  425.     Clen += len;
  426.     if (len < Columns - (ep->Column - ep->Topcolumn)) {
  427.         ScrollRaster(rp, -len * Xsize, 0 ,
  428.         COL(ep->Column - ep->Topcolumn),
  429.         ROW(ep->Line - ep->Topline),
  430.         COL(Columns) - 1,
  431.         ROW(ep->Line - ep->Topline + 1) - 1
  432.         );
  433.     }
  434.     }
  435.     i = (ep->Column - ep->Topcolumn + len > Columns) ? Columns - ep->Column + ep->Topcolumn : len;
  436.     setpen(ep->Line);
  437.     Move(rp, COLT(ep->Column - ep->Topcolumn), ROWT(ep->Line - ep->Topline));
  438.     Text(rp, str, i);
  439.     ep->Column += len;
  440.     if (ep->Column - ep->Topcolumn >= Columns)
  441.     text_sync();
  442. fail:
  443.     if (Comlinemode == 0 && ep->Wordwrap)
  444.     do_reformat(0);
  445. }
  446.  
  447. void
  448. do_up()
  449. {
  450.     ED *ep = Ep;
  451.     RP *rp = ep->Win->RPort;
  452.  
  453.     if (ep->Line) {
  454.     text_sync();
  455.     --ep->Line;
  456.     text_load();
  457.     if (Ep->Line < Ep->Topline) {
  458.         if (Nsu == 0) {
  459.         ScrollRaster(rp,0,-Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
  460.         --ep->Topline;
  461.         text_displayseg(0, 1);
  462.         }
  463.     }
  464.     } else {
  465.     Abortcommand = 1;
  466.     }
  467. }
  468.  
  469. void
  470. do_scrolldown()
  471. {
  472.     ED *ep = Ep;
  473.     RP *rp = ep->Win->RPort;
  474.  
  475.     if (ep->Topline + Rows < ep->Lines) {
  476.     if (Nsu == 0) {
  477.         text_sync();
  478.         ScrollRaster(rp,0,Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
  479.         ++ep->Topline;
  480.         ++ep->Line;
  481.         text_load();
  482.         text_displayseg(Rows-1, 1);
  483.     }
  484.     } else {
  485.     Abortcommand = 1;
  486.     }
  487. }
  488.  
  489. void
  490. do_scrollup()
  491. {
  492.     ED *ep = Ep;
  493.     RP *rp = ep->Win->RPort;
  494.  
  495.     if (ep->Topline) {
  496.     if (Nsu == 0) {
  497.         text_sync();
  498.         ScrollRaster(rp,0,-Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
  499.         --ep->Topline;
  500.         --ep->Line;
  501.         text_load();
  502.         text_displayseg(0, 1);
  503.     }
  504.     } else {
  505.     Abortcommand = 1;
  506.     }
  507. }
  508.  
  509. void
  510. do_down()
  511. {
  512.     ED *ep = Ep;
  513.     RP *rp = ep->Win->RPort;
  514.  
  515.     if (ep->Line + 1 < ep->Lines) {
  516.     text_sync();
  517.     ++ep->Line;
  518.     text_load();
  519.     if (ep->Line - ep->Topline >= Rows) {
  520.         if (Nsu == 0) {
  521.         ScrollRaster(rp,0,Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
  522.         ++ep->Topline;
  523.         text_displayseg(Rows-1, 1);
  524.         }
  525.     }
  526.     } else {
  527.     Abortcommand = 1;
  528.     }
  529. }
  530.  
  531. /*
  532.  *  PAGEUP
  533.  *  PAGEDOWN
  534.  *  PAGESET n    (n = 0 to 100 for percentage of #rows to scroll, minimum 1)
  535.  *        can be > 100.
  536.  */
  537.  
  538. void
  539. do_page()
  540. {
  541.     int n, multiplier = 1;
  542.     ED *ep = Ep;
  543.     static short pctg = 80;
  544.  
  545.     switch(av[0][4]) {
  546.     case 'u':
  547.     multiplier = -1;
  548.     case 'd':
  549.     n = multiplier * Rows * pctg / 100;
  550.     if (!n)
  551.         n = multiplier;
  552.     if (n > 0 && ep->Topline >= ep->Lines - Rows)
  553.         return;
  554.     text_sync();
  555.     ep->Line += n;
  556.     ep->Topline += n;
  557.     if (ep->Line >= ep->Lines)
  558.         ep->Line = ep->Lines - 1;
  559.     if (ep->Line < 0)
  560.         ep->Line = 0;
  561.     if (ep->Topline >= ep->Lines)
  562.         ep->Topline = ep->Lines - Rows - 1;
  563.     if (ep->Topline < 0)
  564.         ep->Topline = 0;
  565.     text_load();
  566.     if (!text_sync())
  567.         text_redisplay();
  568.     break;
  569.     case 's':
  570.     pctg = atoi(av[1]);
  571.     break;
  572.     }
  573. }
  574.  
  575. void
  576. do_downadd()
  577. {
  578.     ED *ep = Ep;
  579.     ubyte *ptr;
  580.  
  581.     if (ep->Line + 1 == ep->Lines) {
  582.     ep->Modified = 1;
  583.     if (makeroom(32) && (ptr = allocb(1))) {
  584.         ep->List[ep->Lines] = ptr;
  585.         *ptr = 0;
  586.         ++ep->Lines;
  587.     } else {
  588.         nomemory();
  589.     }
  590.     }
  591.     do_down();
  592. }
  593.  
  594. void
  595. do_left()
  596. {
  597.     ED *ep = Ep;
  598.  
  599.     if (ep->Column) {
  600.     --ep->Column;
  601.     if (ep->Column < ep->Topcolumn)
  602.         text_sync();
  603.     } else {
  604.     Abortcommand = 1;
  605.     }
  606. }
  607.  
  608. void
  609. do_right()
  610. {
  611.     ED *ep = Ep;
  612.  
  613.     if (ep->Column != 254) {
  614.     if (Current[ep->Column] == 0) {
  615.         Current[ep->Column] = ' ';
  616.         Current[ep->Column+1]= '\0';
  617.         ++Clen;
  618.     }
  619.     ++ep->Column;
  620.     if (ep->Column - ep->Topcolumn >= Columns)
  621.         text_sync();
  622.     } else {
  623.     Abortcommand = 1;
  624.     }
  625. }
  626.  
  627. void
  628. do_tab()
  629. {
  630.     short n;
  631.     ED *ep = Ep;
  632.  
  633.     for (n = ep->Tabstop-(ep->Column % ep->Tabstop); n > 0; --n)
  634.     do_right();
  635. }
  636.  
  637. void
  638. do_backtab()
  639. {
  640.     short n;
  641.     ED *ep = Ep;
  642.  
  643.     n = ep->Column % ep->Tabstop;
  644.     if (!n)
  645.     n = ep->Tabstop;
  646.     for (; n > 0; --n)
  647.     do_left();
  648. }
  649.  
  650. void
  651. do_return()
  652. {
  653.     ubyte buf[256];
  654.     char *partial;
  655.  
  656.     if (Comlinemode) {
  657.     strcpy(buf, Current);
  658.     strcpy(RecallBuf, Current);
  659.     partial = Partial;
  660.     Partial = NULL;
  661.     escapecomlinemode();
  662.     if (partial) {
  663.         if (do_command(buf))
  664.         do_command(partial);
  665.         free(partial);
  666.     } else {
  667.         do_command(buf);
  668.     }
  669.     } else {
  670.     Ep->Column = 0;
  671.     text_sync();
  672.     do_downadd();
  673.     }
  674. }
  675.  
  676. void
  677. do_bs()
  678. {
  679.     ED *ep = Ep;
  680.     RP *rp = ep->Win->RPort;
  681.  
  682.     if (ep->Column) {
  683.     movmem(Current + ep->Column, Current + ep->Column - 1, Clen - ep->Column + 1);
  684.     --ep->Column;
  685.     --Clen;
  686.     if (ep->Column < ep->Topcolumn) {
  687.         text_sync();
  688.     } else {
  689.         ScrollRaster(rp, Xsize, 0,
  690.         COL(ep->Column - ep->Topcolumn),
  691.         ROW(ep->Line   - ep->Topline),
  692.         COL(Columns)-1,
  693.         ROW(ep->Line - ep->Topline + 1)-1
  694.         );
  695.         if (Clen >= ep->Topcolumn + Columns) {
  696.         setpen(ep->Line);
  697.         Move(rp, COLT(Columns-1), ROWT(ep->Line - ep->Topline));
  698.         Text(rp, Current + ep->Topcolumn + Columns - 1, 1);
  699.         }
  700.     }
  701.     if (Comlinemode == 0 && ep->Wordwrap)
  702.         do_reformat(0);
  703.     } else {
  704.     Abortcommand = 1;
  705.     }
  706. }
  707.  
  708.  
  709. /*
  710.  * esc, escimm
  711.  */
  712.  
  713. int Savetopline, Savecolumn, Savetopcolumn;
  714.  
  715. void
  716. do_recall()
  717. {
  718.     av[0] = (ubyte *)"escimm";
  719.     av[1] = (ubyte *)RecallBuf;
  720.     do_esc();
  721. }
  722.  
  723. void
  724. do_esc()
  725. {
  726.     ED *ep = Ep;
  727.     RP *rp = ep->Win->RPort;
  728.  
  729.     if (Comlinemode) {
  730.     escapecomlinemode();
  731.     return;
  732.     }
  733.     text_sync();
  734.     if (av[0][3] == 'i')
  735.     strcpy(Current, av[1]);
  736.     else
  737.     Current[0] = 0;
  738.     Clen = strlen(Current);
  739.     Comlinemode = 1;
  740.     returnoveride(1);
  741.     Savetopline = ep->Topline;
  742.     Savecolumn    = ep->Column;
  743.     Savetopcolumn = ep->Topcolumn;
  744.     ep->Column      = Clen;
  745.     ep->Topcolumn = 0;
  746.     ep->Topline   = ep->Line - Rows + 1;
  747.     SetAPen(rp, ep->BGPen);
  748.     RectFill(rp, COL(0), ROW(Rows-1), Xbase + Xpixs - 1, Ybase + Ypixs - 1);
  749.     SetAPen(rp, ep->FGPen);
  750.     Move(rp, COL(0), ROW(Rows-1) - 1);
  751.     Draw(rp, Xbase + Xpixs - 1, ROW(Rows - 1) - 1);
  752.     text_displayseg(Rows - 1, 1);
  753. }
  754.  
  755. void
  756. escapecomlinemode()
  757. {
  758.     ED *ep = Ep;
  759.     RP *rp = ep->Win->RPort;
  760.  
  761.     if (Partial) {
  762.     free(Partial);
  763.     Partial = NULL;
  764.     }
  765.     if (Comlinemode) {
  766.     strcpy(RecallBuf, Current);
  767.     Comlinemode = 0;
  768.     returnoveride(0);
  769.     ep->Topline = Savetopline;
  770.     ep->Column  = Savecolumn;
  771.     ep->Topcolumn = Savetopcolumn;
  772.     text_load();
  773.     SetAPen(rp, ep->BGPen);
  774.     RectFill(rp, COL(0), ROW(Rows-1)-1, Xbase + Xpixs - 1, Ybase + Ypixs - 1);
  775.     SetAPen(rp, ep->FGPen);
  776.     text_displayseg(Rows - 2, 2);
  777.     }
  778. }
  779.  
  780. void
  781. do_del()
  782. {
  783.     ED *ep = Ep;
  784.     RP *rp = ep->Win->RPort;
  785.  
  786.     if (Current[ep->Column]) {
  787.     movmem(Current + ep->Column + 1, Current + ep->Column, Clen - ep->Column);
  788.     --Clen;
  789.     ScrollRaster(rp, Xsize, 0,
  790.         COL(ep->Column - ep->Topcolumn),
  791.         ROW(ep->Line - ep->Topline),
  792.         COL(Columns)-1,
  793.         ROW(ep->Line - ep->Topline + 1) - 1
  794.     );
  795.     if (Clen >= ep->Topcolumn + Columns) {
  796.         setpen(ep->Line);
  797.         Move(rp, COLT(Columns-1), ROWT(ep->Line-ep->Topline));
  798.         Text(rp, Current+ep->Topcolumn+Columns-1, 1);
  799.     }
  800.     if (Comlinemode == 0 && ep->Wordwrap)
  801.         do_reformat(0);
  802.     }
  803. }
  804.  
  805. void
  806. do_top()
  807. {
  808.     text_sync();
  809.     Ep->Line = 0;
  810.     text_load();
  811.     text_sync();
  812. }
  813.  
  814. void
  815. do_bottom()
  816. {
  817.     text_sync();
  818.     Ep->Line = Ep->Lines - 1;
  819.     text_load();
  820.     text_sync();
  821. }
  822.  
  823. void
  824. do_firstcolumn()
  825. {
  826.     if (Ep->Column) {
  827.     Ep->Column = 0;
  828.     text_sync();
  829.     }
  830. }
  831.  
  832. void
  833. do_firstnb()
  834. {
  835.     for (Ep->Column = 0; Current[Ep->Column] == ' '; ++Ep->Column);
  836.     if (Current[Ep->Column] == 0)
  837.     Ep->Column = 0;
  838.     text_sync();
  839. }
  840.  
  841. void
  842. do_lastcolumn()
  843. {
  844.     short i;
  845.  
  846.     text_sync();
  847.     i = (Comlinemode) ? Clen : strlen(Ep->List[Ep->Line]);
  848.     if (i != Ep->Column) {
  849.     Ep->Column = i;
  850.     text_sync();
  851.     }
  852. }
  853.  
  854. /*
  855.  * GOTO [+/-]N
  856.  * GOTO BLOCK    start of block
  857.  * GOTO START    start of block
  858.  * GOTO END    end of block
  859.  */
  860.  
  861. void
  862. do_goto()
  863. {
  864.     short n, i;
  865.     ubyte *ptr = av[1];
  866.  
  867.     i = 0;
  868.     n = -1;
  869.  
  870.     switch(*ptr) {
  871.     case 'b':
  872.     case 's':
  873.     case 'B':
  874.     case 'S':
  875.     n = -1;
  876.     if (Ep == BEp)
  877.         n = BSline;
  878.     break;
  879.     case 'e':
  880.     case 'E':
  881.     n = -1;
  882.     if (Ep == BEp)
  883.         n = BEline;
  884.     break;
  885.     case '+':
  886.     i = 1;
  887.     case '-':
  888.     n = Ep->Line;
  889.     default:
  890.     n += atoi(ptr+i);
  891.     }
  892.     if (n >= Ep->Lines)
  893.     n = Ep->Lines - 1;
  894.     if (n < 0)
  895.     n = 0;
  896.     text_sync();
  897.     Ep->Line = n;
  898.     text_load();
  899.     text_sync();
  900. }
  901.  
  902. void
  903. do_screentop()
  904. {
  905.     text_sync();
  906.     Ep->Line = Ep->Topline;
  907.     text_load();
  908.     text_sync();
  909. }
  910.  
  911. void
  912. do_screenbottom()
  913. {
  914.     text_sync();
  915.     Ep->Line = Ep->Topline + Rows - 1;
  916.     if (Ep->Line < 0 || Ep->Line >= Ep->Lines)
  917.     Ep->Line = Ep->Lines - 1;
  918.     text_load();
  919.     text_sync();
  920. }
  921.  
  922. static ubyte Fstr[256];
  923. static ubyte Rstr[256];
  924. static short Srch_sign;
  925. static char Doreplace;
  926.  
  927. /*
  928.  * findstr, repstr
  929.  */
  930.  
  931. void
  932. do_findstr()
  933. {
  934.     if (av[0][0] == 'f')
  935.     strcpy(Fstr, av[1]);
  936.     else
  937.     strcpy(Rstr, av[1]);
  938. }
  939.  
  940. /*
  941.  * findr, nextr, prevr
  942.  */
  943.  
  944. void
  945. do_findr()
  946. {
  947.     Doreplace = 1;
  948.     Srch_sign = 1;
  949.     switch(av[0][0]) {
  950.     case 'f':
  951.     strcpy(Fstr, av[1]);
  952.     strcpy(Rstr, av[2]);
  953.     break;
  954.     case 'p':
  955.     Srch_sign = -1;
  956.     break;
  957.     }
  958.     search_operation();
  959. }
  960.  
  961. /*
  962.  * find, next, prev
  963.  */
  964.  
  965. void
  966. do_find()
  967. {
  968.     Doreplace = 0;
  969.     Srch_sign = 1;
  970.     switch(av[0][0]) {
  971.     case 'f':
  972.     strcpy(Fstr, av[1]);
  973.     break;
  974.     case 'p':
  975.     Srch_sign = -1;
  976.     break;
  977.     }
  978.     search_operation();
  979. }
  980.  
  981.  
  982. static char CaseIgnore;
  983.  
  984. void
  985. search_operation()
  986. {
  987.     int flen = strlen(Fstr);
  988.     int rlen = strlen(Rstr);
  989.     char senabled = 0;
  990.     ubyte *ptr;
  991.     int i, col;
  992.     ED *ep = Ep;
  993.  
  994.     CaseIgnore = ep->IgnoreCase;
  995.     text_sync();
  996.     if (!flen) {
  997.     title("No find pattern");
  998.     Abortcommand = 1;
  999.     return;
  1000.     }
  1001.  
  1002.     col = ep->Column;
  1003.     if (col >= strlen(ep->List[ep->Line]))
  1004.     col = strlen(ep->List[ep->Line]);
  1005.     for (i = ep->Line;;) {
  1006.     ptr = ep->List[i];
  1007.     if (Srch_sign > 0) {
  1008.         while (ptr[col]) {
  1009.         if (senabled && case_strncmp(Fstr,ptr+col,flen) == 0)
  1010.             goto found;
  1011.         senabled = 1;
  1012.         ++col;
  1013.         }
  1014.         senabled = 1;
  1015.         if (++i >= ep->Lines)
  1016.         break;
  1017.         col = 0;
  1018.     } else {
  1019.         while (col >= 0) {
  1020.         if (senabled && case_strncmp(Fstr,ptr+col,flen) == 0)
  1021.             goto found;
  1022.         senabled = 1;
  1023.         --col;
  1024.         }
  1025.         senabled = 1;
  1026.         if (--i < 0)
  1027.         break;
  1028.         col = strlen(ep->List[i]);
  1029.     }
  1030.     }
  1031.     title("Pattern Not Found");
  1032.     Abortcommand = 1;
  1033.     return;
  1034.  
  1035. found:
  1036.     ep->Line = i;
  1037.     ep->Column = col;
  1038.  
  1039.     text_load();
  1040.     if (Doreplace) {
  1041.     if (rlen > flen && rlen-flen+strlen(ptr) > 254) {
  1042.         title("Replace: Line Too Long");
  1043.         Abortcommand = 1;
  1044.         return;
  1045.     }
  1046.     if (Clen-col-flen >= 0) {
  1047.         movmem(Current+col+flen, Current+col+rlen, Clen-col-flen+1);
  1048.         movmem(Rstr, Current+col, rlen);
  1049.         Clen += rlen-flen;
  1050.         ep->Column += rlen;
  1051.     }
  1052.     text_sync();
  1053.     text_redisplaycurrline();
  1054.     } else {
  1055.     text_sync();
  1056.     }
  1057. }
  1058.  
  1059. case_strncmp(s1, s2, len)
  1060. char *s1, *s2;
  1061. {
  1062.     if (CaseIgnore == 0)
  1063.     return(strncmp(s1, s2, len));
  1064.     for (; len; --len, ++s1, ++s2) {
  1065.     if ((*s1|0x20) != (*s2|0x20))
  1066.         return(1);
  1067.     if (((*s1 >= 'a' && *s1 <= 'z') || (*s1 >= 'A' && *s1 <= 'Z')) &&
  1068.         ((*s2 >= 'a' && *s2 <= 'z') || (*s2 >= 'A' && *s2 <= 'Z')))
  1069.     {
  1070.         continue;
  1071.     }
  1072.     if (*s1 != *s2)
  1073.         return(1);
  1074.     }
  1075.     return(0);
  1076. }
  1077.  
  1078.  
  1079.