home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff284.lzh / Dme / src / cmd1.c < prev    next >
C/C++ Source or Header  |  1989-11-27  |  17KB  |  1,010 lines

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