home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / vos2-121.zip / v / texted / vseeci.cpp < prev    next >
C/C++ Source or Header  |  1998-10-01  |  24KB  |  1,072 lines

  1.  
  2. #include "vseeci.h"
  3. #include <v/vcmdwin.h>
  4. #include <v/vfilesel.h>
  5. #include <fstream.h>
  6.  
  7.     static int filterIndex = 0;
  8.     static char* filter[] =
  9.       {
  10.         "*",
  11.         "*.txt",
  12.         "*.c;*.cpp;*.cxx;*.h",
  13.         0
  14.       };
  15.  
  16. // ==================>>> vSeeCI::vSeeCI <<<=================
  17.   vSeeCI::vSeeCI(vTextEditor* textEd, vCmdWindow* cw)
  18.         : vTextEdCmdInterp(textEd, cw)
  19.   {
  20.  
  21.     lex_def = 1;
  22.     CmdCount = 1;
  23.     param_count = 1;
  24.     cmdmode = Cmd;
  25.     countWait = 0;        // start in cmdmode
  26.     slastl = savlen = nxtsav = 0;    // Save Buff stuff
  27.     _SaveBuff  = new char*[SBAllocLines];    // build save in 500 line incrs.
  28.     for (long lx = 0 ; lx < SBAllocLines ; ++lx)
  29.         _SaveBuff[lx] = 0;
  30.  
  31.     _maxSBLines = SBAllocLines - 1;
  32.   }
  33.  
  34. // ==================>>> vSeeCI::~vSeeCI <<<================
  35.   vSeeCI::~vSeeCI()
  36.   {
  37.     if (_SaveBuff)
  38.       {
  39.     for (long lx = 0 ; lx < _maxSBLines ;++lx)    // delete contents
  40.       {
  41.         if (_SaveBuff[lx])
  42.         delete [] _SaveBuff[lx];
  43.       }
  44.     delete [] _SaveBuff;    // free SaveBuff    // delete line array
  45.       }
  46.   }
  47.  
  48. // =====================>>> vTextEdCmdInterp::InitCmdInterp <<<====================
  49.   void vSeeCI::InitCmdInterp()
  50.   {
  51.     te()->ChangeInsMode(te()->GetEdState().ins_mode,"Command ");
  52.   }
  53.  
  54. // =====================>>> vSeeCI::ProcessKey <<<====================
  55.   int vSeeCI::ProcessKey(vKey key, unsigned int shift)
  56.   {
  57.  
  58.     if (vk_IsModifier(key))             // ignore modifiers
  59.     return -1;
  60.  
  61.  
  62. //    return vTextEdCmdInterp::ProcessKey(key,shift);
  63.     return edit(key,shift);
  64.   }
  65.  
  66. // =============================>>> vSeeCI::edit   <<<==========================
  67.   int vSeeCI::edit(vKey chr, unsigned int shift)
  68.   {
  69.     // Hard wired See command interp.
  70.  
  71.     int s_succ, retval;
  72.  
  73.     static int ins_set[] =        /* allowable commands for insert */
  74.       {
  75.     'i', 'o', 'X'-'@', 'T'-'@', 'g', 'Y'-'@', 'y', 0
  76.       };
  77.  
  78.     static int jump_set[] =    /* commands to not reset jump memory */
  79.       {
  80.     'j', 'm', '?', 'n', 0
  81.       };
  82.  
  83.  
  84.     vKey lexval = chr;         // @@ For now, simple translation
  85.  
  86.     if (cmdmode == Ins)        // in insert mode
  87.       {
  88.     // This code allows the keypad keys to still move
  89.     // the cursor around while still staying in insert mode...
  90.     retval = 1;
  91.     switch (lexval)
  92.       {
  93.         case vk_BackSpace:        /* delete last character */
  94.         retval = te()->charDelete(-CmdCount);
  95.         break;
  96.  
  97.         case vk_Delete:
  98.         case vk_KP_Delete:
  99.           {
  100.         if (shift & VKM_Shift || shift & VKM_Ctrl)
  101.             te()->lineDelete(CmdCount);
  102.         else
  103.             retval = te()->charDelete(CmdCount);
  104.         break;
  105.           }
  106.  
  107. #ifdef CMDS_IN_INSERT
  108.         case vk_Home:
  109.         case vk_KP_Home:
  110.           {
  111.         if (shift & VKM_Shift || shift & VKM_Ctrl)
  112.             retval = te()->lineGoto(1);
  113.         else
  114.             te()->lineBeginning();
  115.         break;
  116.           }
  117.  
  118.         case vk_End:
  119.         case vk_KP_End:
  120.           {
  121.         if (shift & VKM_Shift || shift & VKM_Ctrl)
  122.             te()->bufferBottom();
  123.         else
  124.             te()->lineEnd();
  125.         break;
  126.           }
  127.  
  128.         case vk_Page_Up:
  129.         case vk_KP_Page_Up:
  130.           {
  131.         if (shift & VKM_Ctrl)
  132.             te()->scrollDown(-CmdCount * te()->GetRows());
  133.         else
  134.             retval = te()->lineDown((long)(-CmdCount * te()->GetRows()));
  135.         break;
  136.           }
  137.  
  138.         case vk_Up:
  139.         case vk_KP_Up:
  140.           {
  141.         if (shift & VKM_Shift)
  142.             retval = te()->lineDownBeg(-CmdCount);
  143.         else
  144.             retval = te()->lineDown(-CmdCount);
  145.         break;
  146.           }
  147.  
  148.         case vk_Page_Down:
  149.         case vk_KP_Page_Down:
  150.           {
  151.         if (shift & VKM_Ctrl)
  152.             te()->scrollDown(CmdCount * te()->GetRows());
  153.         else
  154.             retval = te()->lineDown(
  155.                   (long) te()->minl((CmdCount * te()->GetRows()),
  156.                   (long)(te()->GetLines() - te()->GetCurLine() + 1)));
  157.         break;
  158.           }
  159.  
  160.         case vk_KP_Down:
  161.         case vk_Down:
  162.           {
  163.         if (shift & VKM_Shift)
  164.             retval = te()->lineDownBeg(CmdCount);
  165.         else
  166.             retval = te()->lineDown(CmdCount);
  167.         break;
  168.           }
  169.  
  170.         case vk_Left:
  171.         case vk_KP_Left:
  172.           {
  173.         if (shift & VKM_Ctrl || shift & VKM_Shift)
  174.             retval = te()->wordRight(-CmdCount);
  175.         else
  176.             retval = te()->charRight(-CmdCount,1);
  177.         break;
  178.           }
  179.  
  180.         case vk_Right:
  181.         case vk_KP_Right:
  182.           {
  183.         if (shift & VKM_Ctrl ||shift & VKM_Shift)
  184.             retval = te()->wordRight(CmdCount);
  185.         else
  186.             retval = te()->charRight(CmdCount,1);
  187.         break;
  188.           }
  189. #endif
  190.  
  191.         case vk_KP_Insert:
  192.         case vk_Insert:
  193.           {
  194.         te()->SetInsMode(!(te()->GetEdState().ins_mode));
  195.         break;
  196.           }
  197.  
  198.         case vk_Escape:
  199.           {
  200.         cmdmode = Cmd;
  201.         te()->ChangeInsMode(te()->GetEdState().ins_mode,"Command ");
  202.         return 1;        // done!
  203.           }
  204.  
  205.             case 'V'-'@':           // ^V: Paste
  206.              {
  207.         te()->EditPaste();
  208.         break;
  209.               }
  210.  
  211.         default:
  212.         retval = te()->defaultKeyIn(lexval, shift);
  213.         break;
  214.       }
  215.  
  216.     return retval;
  217.       }
  218.     else if (cmdmode == Find)        // in Find pattern mode
  219.       {
  220.         char tmp[2] = "x";
  221.         if (chr == vk_Escape)
  222.           {
  223.             cmdmode = Cmd;
  224.             te()->ChangeInsMode(te()->GetEdState().ins_mode,"Command ");
  225.             te()->SetFindPat(newFindPat);
  226.         return te()->EditCommand(edFindNext, CmdCount);
  227.           }
  228.         else if (chr == vk_BackSpace)
  229.           {
  230.             int pl = strlen(newFindPat);
  231.  
  232.             if (pl > 0)
  233.               newFindPat[pl-1] = 0;    // wipe last char
  234.             te()->StatusMessage(newFindPat);
  235.             return 1;
  236.           }
  237.         tmp[0] = lexval;    // add to pattern
  238.         if (strlen(newFindPat) < MAX_LINE)
  239.           {
  240.             strcat(newFindPat, tmp);
  241.           }
  242.         te()->StatusMessage(newFindPat);
  243.         return 1;
  244.       }
  245.  
  246.     te()->ChangeInsMode(te()->GetEdState().ins_mode,"Command ");
  247.  
  248.     if (lexval >= '0' && lexval <= '9' || lexval == '-')
  249.       {
  250.     if (countWait == 0)
  251.       {
  252.         countWait = 1;
  253.         if (lexval == '-')
  254.           {
  255.         CmdCount = 1;    // - implies 1
  256.         countWait = -1;
  257.           }
  258.         else
  259.         CmdCount = lexval - '0';
  260.         return 1;
  261.       }
  262.     else if (lexval == '-')
  263.       {
  264.         countWait = -1;
  265.         return 1;
  266.       }
  267.     else if (lexval >= '0' && lexval <= '9')      // it is a count
  268.       {
  269.         if (countWait < 0 && CmdCount == 1)
  270.         CmdCount = 0;            // user entering value
  271.         CmdCount = (CmdCount * 10) + (lexval - '0');
  272.         return 1;
  273.       }
  274.       }
  275.  
  276.     if (countWait != 0)
  277.       {
  278.     CmdCount *= countWait;        // negative?
  279.     countWait = 0;                      // done building count
  280.       }
  281.  
  282.  
  283.     s_succ = 1;
  284.  
  285.     if (te()->GetCurLine() < 1)    // make sure legal command for empty buffer
  286.       {
  287.     if (!inset(lexval,ins_set))
  288.       {
  289.         te()->StatusMessage("Can't, buffer empty. Insert 1st ");
  290.         return 1;
  291.       }
  292.       }
  293.  
  294. //    if (did_insert)            /* was last command an insert? */
  295. //      {
  296. //    auto_tidy();            /* auto format text */
  297. //    did_insert = 0;
  298. //      }
  299.  
  300.     if (!inset(lexval,jump_set))
  301.     te()->SetJLine(te()->GetCurLine()); // sets previous line for Jump
  302.  
  303.     switch (lexval)
  304.       {
  305.         case 'C'-'@':           // ^C : Copy ; Shift-^C: fold case
  306.           {
  307.             te()->EditCopy();
  308.             break;
  309.           }
  310.  
  311.     case 'D'-'@':             /* down in column */
  312.     case vk_KP_Down:
  313.     case vk_Down:
  314.       {
  315.         if (shift & VKM_Shift)
  316.         retval = te()->lineDownBeg(CmdCount);
  317.         else
  318.         retval = te()->lineDown(CmdCount);
  319.         break;
  320.       }
  321.  
  322.     case 'E'-'@':            /* edit repeat buffer */
  323.    //        if (lex_def)        /* default 1 passed */
  324.    //        CmdCount = rptuse + 1;    /* use current repeat loop */
  325.     //        retval = edit_rpt(CmdCount);    /* edit repeat buffer */
  326.         break;
  327.  
  328.     case 'F'-'@':           // ^F: find next, Shift-^F: find/replace
  329.       {
  330.         if (shift & VKM_Shift)      // Shift-^F
  331.           {
  332.         retval = te()->EditCommand(edFindNext, CmdCount);
  333.         //ED(target) = T_FIND_RPL;
  334.         // (void) build_find(0,1,(int)CmdCount);    /* set up find build first */
  335.           }
  336.         else
  337.           {
  338.         retval = te()->EditCommand(edFindNext, CmdCount);
  339.           }
  340.         break;
  341.       }
  342.  
  343.     case 'G'-'@':            /* unkill last line killed */
  344. //@@        retval = unkill();
  345.         break;
  346.  
  347.     case vk_BackSpace:        /* delete last character */
  348.         retval = te()->charDelete(-CmdCount);
  349.         break;
  350.  
  351.     case vk_Tab:
  352.       {
  353.         retval = te()->wordRight(CmdCount);
  354.       }
  355.  
  356.     case 'J'-'@':            /* set range by character */
  357. //@@        retval = add_to_range(CmdCount,0);
  358.         break;
  359.  
  360.     case 'K'-'@':           // ^K: Kill line
  361.       {
  362.         te()->lineDelete(CmdCount);
  363.         break;
  364.       }
  365.  
  366.     case 'L'-'@':            /* goto line */
  367.       {
  368.         retval = te()->lineGoto(CmdCount);
  369.         break;
  370.       }
  371.  
  372.     case 'M'-'@':            /* (RETURN) set range */
  373.         //        retval = add_to_range(CmdCount,1);
  374.         break;
  375.  
  376.     case 'N'-'@':            /* return to noted location */
  377.       {
  378.             retval = te()->EditCommand(edNoteGoto,CmdCount);
  379.         break;
  380.       }
  381.  
  382.     case 'P'-'@':            /* page up */
  383.       {
  384.         retval = te()->lineDown((long)(-CmdCount * te()->GetRows()));
  385.         break;
  386.       }
  387.  
  388.     case vk_Page_Up:
  389.     case vk_KP_Page_Up:
  390.       {
  391.         if (shift & VKM_Ctrl)
  392.         te()->scrollDown(-CmdCount * te()->GetRows());
  393.         else
  394.         retval = te()->lineDown((long)(-CmdCount * te()->GetRows()));
  395.         break;
  396.       }
  397.  
  398.         case 'Q'-'@':            // ^Q - save/close this file
  399.           {
  400.             cmdWin()->WindowCommand(M_SaveClose,1,(CmdType)0);
  401.             break;
  402.           }
  403.  
  404.     case 'T'-'@':            /* abort */
  405. //@@        abort_session();
  406.         break;
  407.  
  408.     case 'U'-'@':             /* up in column */
  409.     case vk_Up:
  410.     case vk_KP_Up:
  411.       {
  412.         if (shift & VKM_Shift)
  413.         retval = te()->lineDownBeg(-CmdCount);
  414.         else
  415.         retval = te()->lineDown(-CmdCount);
  416.         break;
  417.       }
  418.  
  419.         case 'V'-'@':           // ^V: Paste
  420.           {
  421.             te()->EditPaste();
  422.             break;
  423.           }
  424.  
  425.         case 'X'-'@':           // ^X : Cut
  426.           {
  427.             te()->EditCut();
  428.             break;
  429.           }
  430.  
  431.     case '"':            /* kill rest of line */
  432.       {
  433.         retval = te()->lineDeleteToEnd();
  434.         break;
  435.       }
  436.  
  437.     case '#':            /* ex. rpt k n times */
  438. //@        ED(target) = T_EXEC_RPT;    /* execute the repeat loop */
  439. //@@        param_count = CmdCount;    /* remember the count */
  440.         break;
  441.  
  442.     case '&':            /* execute repeat buffer again */
  443. //&&        if (CmdCount != 1)
  444. //&&        ED(echof)=FALSE;    /* turn off echo */
  445. //&&        rptcnt[rptuse] = CmdCount > 0 ? CmdCount : (-CmdCount);
  446.         break;
  447.  
  448.     case '\'':            /* kill previous part of line */
  449.       {
  450.         retval = te()->lineDeleteFront();
  451.         break;
  452.       }
  453.  
  454.     case '*':            /* insert the find pattern */
  455. //@@        succ = ins_pat();
  456.         break;
  457.  
  458.     case '+':            /* insert counter value */
  459. //@@        ins_counter();
  460.         break;
  461.  
  462.     case ',':            /* move to beginning of line */
  463.       {
  464.         te()->lineBeginning();
  465.         break;
  466.       }
  467.  
  468.     case '.':            /* move to end of the line */
  469.       {
  470.         te()->lineEnd();
  471.         break;
  472.       }
  473.  
  474.     case '/':            /* delete last thing manipulated */
  475.         retval = RemoveLast();
  476.         break;
  477.  
  478.     case ';':            /* find again */
  479.       {
  480.         // @@ add code to handle Finds from repeat buffer
  481.         retval = te()->EditCommand(edFindNext, CmdCount);
  482.         break;
  483.       }
  484.  
  485.     case '<':            /* define/execute repeat loop */
  486. //@@        ED(target) = T_RPT;
  487. //@@        (void) rpt_build(0,1,CmdCount);
  488.         break;
  489.  
  490.     case '=':            /* remove last and enter insert mode */
  491.       {
  492.         if ((retval = RemoveLast()))
  493.           {
  494.         cmdmode = Ins;
  495.         te()->ChangeInsMode(te()->GetEdState().ins_mode);
  496.           }
  497.         break;
  498.       }
  499.  
  500.     case '@':            /* execute key macro */
  501. //@@        param_count = CmdCount;    /* remember the count */
  502. //@@        ED(target) = T_EXEC_KM;
  503.         break;
  504.  
  505.     case '[':            /* backwards jump over word */
  506.       {
  507.         retval = te()->wordRight(-CmdCount);
  508.         break;
  509.       }
  510.  
  511.     case '\\':            /* replace */
  512. //@@        succ = replace();
  513.         break;
  514.  
  515.     case ']':            /* balance match */
  516.       {
  517.         retval = te()->BalMatch(CmdCount);
  518.         break;
  519.       }
  520.  
  521.     case '^':            /* reverse find */
  522. //@@        ED(target) = T_FIND;
  523. //@@        (void) build_find(0,1,(int)(-CmdCount)); /* set up find build first */
  524.         break;
  525.  
  526.     case '_':            /* kill word */
  527. //@@        if (!(succ = wordr(CmdCount)))
  528. //@@        break;
  529. //@@        retval = rmvlst();
  530.         break;
  531.  
  532.     case 'a':            /* append to save buffer */
  533.         retval = save(CmdCount,1);
  534.         break;
  535.  
  536.     case 'b':            /* goto top of page */
  537.       {
  538.         retval = te()->lineGoto(1);
  539.         break;
  540.       }
  541.  
  542.     case vk_Home:
  543.     case vk_KP_Home:
  544.       {
  545.         if (shift & VKM_Shift || shift & VKM_Ctrl)
  546.         retval = te()->lineGoto(1);
  547.         else
  548.         te()->lineBeginning();
  549.         break;
  550.       }
  551.  
  552.     case 'c':            /* change characters */
  553.         if ((retval = te()->charDelete(CmdCount)) )
  554.           {
  555.         cmdmode = Ins;
  556.         te()->ChangeInsMode(te()->GetEdState().ins_mode);
  557.           }
  558.  
  559.         break;
  560.  
  561.     case 'D':
  562.     case 'd':             /* down line */
  563.         retval = te()->lineDownBeg(CmdCount);
  564.         break;
  565.  
  566.     case 'e':            /* goto to bottom of page */
  567.         te()->bufferBottom();
  568.         break;
  569.  
  570.     case vk_End:
  571.     case vk_KP_End:
  572.       {
  573.         if (shift & VKM_Shift || shift & VKM_Ctrl)
  574.         te()->bufferBottom();
  575.         else
  576.         te()->lineEnd();
  577.         break;
  578.       }
  579.  
  580.     case 'f':        // F: set find pattern only - unechoed
  581.           {
  582.             cmdmode = Find;
  583.             te()->ChangeInsMode(te()->GetEdState().ins_mode,"Find Pat");
  584.             newFindPat[0] = 0;    // no pattern yet
  585.             break;
  586.           }
  587.  
  588.     case 'F':        // f: find via dialog
  589.       {
  590.         // @@ add code to handle Finds from repeat buffer
  591.             te()->SetFindPat("");    // new pattern each time!
  592.         retval = te()->EditCommand(edFind, CmdCount);
  593.         break;
  594.       }
  595.  
  596.     case 'g':            /* get move buffer */
  597.         retval = getsav();
  598.         break;
  599.  
  600.     case 'I':
  601.         if (CmdCount >= 1)
  602.         retval = te()->charInsert(CmdCount);
  603.         break;
  604.  
  605.     case 'i':             /* insert */
  606.         cmdmode = Ins;
  607.         te()->ChangeInsMode(te()->GetEdState().ins_mode);
  608.         break;
  609.  
  610.     case 'j':            /* jump back to last location */
  611.       {
  612.         long itmp = te()->GetCurLine();
  613.         retval = te()->lineGoto(te()->JLine());
  614.         te()->SetJLine(itmp);
  615.         break;
  616.       }
  617.  
  618.     case 'k':             /* delete next character */
  619.         retval = te()->charDelete(CmdCount);
  620.         break;
  621.  
  622.     case vk_Delete:
  623.     case vk_KP_Delete:
  624.       {
  625.         if (shift & VKM_Shift || shift & VKM_Ctrl)
  626.         te()->lineDelete(CmdCount);
  627.         else
  628.         retval = te()->charDelete(CmdCount);
  629.         break;
  630.       }
  631.  
  632.     case 'l':             /* left */
  633.         retval = te()->charRight(-CmdCount,1);
  634.         break;
  635.  
  636.     case vk_Left:
  637.     case vk_KP_Left:
  638.       {
  639.         if (shift & VKM_Ctrl || shift & VKM_Shift)
  640.         retval = te()->wordRight(-CmdCount);
  641.         else
  642.         retval = te()->charRight(-CmdCount,1);
  643.         break;
  644.       }
  645.  
  646.     case 'n':            /* save current location */
  647.             retval = te()->EditCommand(edNoteLocation, CmdCount);
  648.         break;
  649.  
  650.     case 'o':            /* open new line */
  651.         retval = te()->lineOpen(CmdCount);
  652.         cmdmode = Ins;
  653.         te()->ChangeInsMode(te()->GetEdState().ins_mode);
  654.         break;
  655.  
  656.     case 'O':            /* overtype */
  657.     case vk_KP_Insert:
  658.     case vk_Insert:
  659.       {
  660.         te()->SetInsMode(!(te()->GetEdState().ins_mode));
  661.         break;
  662.       }
  663.  
  664.     case 'p':            /* page down screen */
  665.         retval = te()->lineDown(
  666.             (long) te()->minl((CmdCount * te()->GetRows()),
  667.             (long)(te()->GetLines() - te()->GetCurLine() + 1)));
  668.         break;
  669.  
  670.     case vk_Page_Down:
  671.     case vk_KP_Page_Down:
  672.       {
  673.         if (shift & VKM_Ctrl)
  674.         te()->scrollDown(CmdCount * te()->GetRows());
  675.         else
  676.         retval = te()->lineDown(
  677.                 (long) te()->minl((CmdCount * te()->GetRows()),
  678.                 (long)(te()->GetLines() - te()->GetCurLine() + 1)));
  679.         break;
  680.       }
  681.  
  682.     case 'r':             /* right */
  683.         retval = te()->charRight(CmdCount,1);
  684.         break;
  685.  
  686.     case vk_Right:
  687.     case vk_KP_Right:
  688.       {
  689.         if (shift & VKM_Ctrl ||shift & VKM_Shift)
  690.         retval = te()->wordRight(CmdCount);
  691.         else
  692.         retval = te()->charRight(CmdCount,1);
  693.         break;
  694.       }
  695.  
  696.     case 's':            /* save lines in move buffer */
  697.         retval = save(CmdCount,0);
  698.         break;
  699.  
  700.     case 't':            /* tidy up screen */
  701.         retval = te()->formatC(CmdCount);
  702.         break;
  703.  
  704.     case 'U':
  705.     case 'u':             /* up line */
  706.         retval = te()->lineDownBeg(-CmdCount);
  707.         break;
  708.  
  709.     case 'v':            /* verify */
  710.         te()->Verify();
  711.         break;
  712.  
  713.  
  714.     case 'Y'-'@':            /* append external file to save buffer */
  715.     case 'y':            /* write save buffer to file */
  716.         retval = yankfile(CmdCount);
  717.         break;
  718.  
  719.     case '~':            /* '~': change case */
  720.         retval = te()->charFoldCase(CmdCount);
  721.         break;
  722.  
  723. //@@    case Cxa:        /* abandon file */
  724. //@@        clear_mark_range();        /* no range now */
  725. //@@        abandon_changes();
  726. //@@        break;
  727.  
  728. //@@    case Cxf:        /* copy selection to find */
  729. //@@        succ = copy_selection(1);
  730. //@@        break;
  731.  
  732. //@@    case Cxk:            /* define/execute key macro */
  733. //@@        ED(target) = T_BUILD_KM;
  734. //@@        (void) km_build(0);
  735. //@@        break;
  736.  
  737.  
  738. //@@    case Cxr:        /* copy selection to replace */
  739. //@@        succ = copy_selection(0);
  740. //@@        break;
  741.  
  742. #ifdef XXXYYYX
  743.     case Cxcf:        /* replace again */
  744.         if (s_succ = succ = do_find(1,1,1))    /* find first */
  745.           {
  746.         succ = replace();            /* do the replacement */
  747.           }
  748.         break;
  749. #endif
  750.  
  751.     default:
  752.         retval = 0;
  753.         break;
  754.       }              /* end of switch */
  755.  
  756.     if (! retval)        // handle repeat loops
  757.     return 0;
  758.     else
  759.     oldlex = lexval;
  760.     CmdCount = 1;
  761.  
  762.     return 1;
  763.   }
  764.  
  765. /* =============================>>> vSeeCI::inset <<<============================= */
  766.   int vSeeCI::inset(int val, int *set)
  767.   {
  768.      /* return true if val is in set set */
  769.  
  770.     while (*set)
  771.     if (val == *set++)
  772.         return 1;
  773.     return 0;
  774.   }
  775.  
  776. /* =============================>>> vSeeCI::rmvlst <<<============================= */
  777.   int vSeeCI::RemoveLast(void)
  778.   {  /* RemoveLast - delete the previous thing found or manipulated
  779.     length of oldlen is set by insert, find, and save
  780.     may also use savlen if set by save */
  781.  
  782.     static int rmv_set[] =
  783.       {
  784.     'f', 'F' - '@', '^', 's', 'g', ';', 'a', 'I'-'@', '[', '_', 0
  785.       };
  786.  
  787.     if (te()->RemoveMarkRange())    /* was a mark range to remove */
  788.     return 1;            /* all done */
  789.  
  790.     if (!inset(oldlex,rmv_set))
  791.     return 0;
  792.  
  793.     te()->ClearMarkRange();        /* no range now */
  794.  
  795.     if (savlen > 0)
  796.       {
  797.         int oldech = te()->GetEdState().echof;
  798.         if (savlen > 1)
  799.             te()->SetEchoF(0);
  800.     if (te()->GetCurLine() == te()->GetLines()-1 && slastl != 0)
  801.       {
  802.         --savlen;    /* reduce the count */
  803.         if (savlen > 0)
  804.           {
  805.         te()->lineDelete(-savlen);    /* kill off previous lines */
  806.               }
  807.         te()->lineDelete((long) 1);        /* kill the last line */
  808.             if (oldech)
  809.                 te()->SetEchoF(oldech);
  810.             te()->Verify();
  811.       }
  812.     else
  813.           {
  814.         te()->lineDelete(-savlen);        /* kill off savlen lines */
  815.             if (oldech)
  816.                 te()->SetEchoF(oldech);
  817.             if (savlen > 1)
  818.                 te()->Verify();
  819.           }
  820.  
  821.       }
  822.     else if (te()->OldLen() != 0)
  823.       {
  824.     if (! te()->charDelete((long)-te()->OldLen()) )
  825.         return 0;
  826.       }
  827.     te()->SetOldLen(0);            /* don't allow multiple deletes! */
  828.     savlen = (-1);
  829.     return 1;
  830.   }
  831.  
  832. // =============================>>> vSeeCI::save   <<<=========================
  833.   int vSeeCI::save(long cnt, int app)
  834.   { /* save - save cnt lines in save buffer */
  835.  
  836.     long l, lend;
  837.  
  838.     int old_ef = te()->GetEdState().echof;       // remember state of echo flag
  839.  
  840.     if (cnt < 0)
  841.     return 0;
  842.  
  843.     if (te()->GetCurLine() == te()->GetLines()-1 && slastl != 0)
  844.       {
  845.     te()->ErrorMsg("Can't save last line twice! ");
  846.     return 0;
  847.       }
  848.  
  849.     te()->SetOldLen(0);            /* use savlin instead */
  850.  
  851.     if ((oldlex != 's' && !app) || cnt == 0)
  852.       {             /* if new save, cnt == 0 and not appending */
  853.         // Clear old save buffer - delete storage for lines
  854.         for (long lx = 0 ; lx < nxtsav ; ++lx)  // copy old lines
  855.         if (_SaveBuff[lx])
  856.                 delete [] _SaveBuff[lx];    // free space
  857.  
  858.         slastl = savlen = nxtsav = 0;    /* reset these guys */
  859.  
  860.     if (cnt == 0)
  861.       {
  862.         return 1;
  863.       }
  864.       }
  865.  
  866.     if (oldlex != 'a' && app)    /* need to reset savlen for append */
  867.     savlen = 0;
  868.  
  869.     if (cnt > 10)
  870.     te()->SetEchoF(0);
  871.  
  872.     lend = (te()->GetCurLine()+cnt-1 < te()->GetLines()-1)
  873.         ? te()->GetCurLine()+cnt-1
  874.         : te()->GetLines()-1 ;
  875.  
  876.     for (l = te()->GetCurLine() ; l <= lend ; ++l)
  877.       {
  878.     if (nxtsav >= _maxSBLines)         // check for max lines
  879.       {
  880.         if (!reallocSaveBuff())
  881.           {
  882.         if (cnt > 10)
  883.           {
  884.             te()->SetEchoF(old_ef);
  885.             te()->Verify();
  886.           }
  887.         te()->ErrorMsg("Not enough memory for save ");
  888.         return 0;
  889.           }
  890.           }
  891.  
  892.         char line[MAX_LINE + 2];
  893.         te()->getLine(line, MAX_LINE, l);    // fetch the line
  894.         char* cp = new char[strlen(line) + 1];
  895.         strcpy(cp, line);
  896.         _SaveBuff[nxtsav++] = cp;    // copy the line to buffer
  897.  
  898.     ++savlen;        /* savlen for rmvlst */
  899.     if (te()->GetCurLine() == te()->GetLines()-1)    /* don't save last line twice! */
  900.       {
  901.         slastl = 1;
  902.         break;
  903.       }
  904.         (void) te()->lineDownBeg(1);
  905.       }
  906.  
  907.     if (cnt > 10)
  908.       {
  909.     te()->SetEchoF(old_ef);
  910.     te()->Verify();
  911.       }
  912.     return 1;
  913.   }
  914.  
  915. //========================>>> vSeeCI::reallocSaveBuff <<<======================
  916.   int vSeeCI::reallocSaveBuff()
  917.   {
  918.     BUFFPTR* oldLines = _SaveBuff;
  919.  
  920.     _SaveBuff  = new char*[_maxSBLines + SBAllocLines];
  921.     if (!_SaveBuff)
  922.       {
  923.     _SaveBuff = oldLines;              // failed to get more lines
  924.     return 0;
  925.       }
  926.  
  927.     long lx;
  928.     for (lx = 0 ; lx <= _maxSBLines ; ++lx)  // copy old lines
  929.     _SaveBuff[lx] = oldLines[lx];
  930.  
  931.     _maxSBLines = _maxSBLines + SBAllocLines - 1;       // safety factor
  932.  
  933.     for (; lx <= _maxSBLines ; ++lx)  // null new lines
  934.     _SaveBuff[lx] = 0;
  935.  
  936.  
  937.     delete [] oldLines;                 // free the old lines
  938.     return 1;
  939.   }
  940.  
  941. //=============================>>> vSeeCI::getsav <<<==========================
  942.   int vSeeCI::getsav()
  943.   { /* ## getsav - get text from save buffer */
  944.  
  945.     long lx;
  946.     int ix;
  947.  
  948.     if (nxtsav <= 0)        /* nothing to get */
  949.       {
  950.     return 1;
  951.       }
  952.  
  953.     int old_ef = te()->GetEdState().echof;
  954.     te()->SetEchoF(0);
  955.  
  956.     te()->ClearMarkRange();        /* no range now */
  957.  
  958.     // If someday I want the insert to be allowed in the middle
  959.     // of a line, then the easiest way is to insert the first line
  960.     // of the save buffer char by char, then bulk insert the rest
  961.     // after the next line. For now, just insert in front of current
  962.     // line.
  963.  
  964.     te()->lineBeginning();            // force to beginning
  965.  
  966.     long curLine = te()->GetCurLine();        // find current line
  967.  
  968.     for (lx = nxtsav - 1 ; lx >= 0 ; --lx)
  969.        te()->insertLine(_SaveBuff[lx], curLine);    // insert the lines backwards
  970.  
  971.     te()->lineDownBeg(nxtsav);            // go back down to where we were
  972.  
  973.     te()->IncChanges();                /* note changes */
  974.  
  975.     te()->SetOldLen(0);                // fix up this stuff
  976.     te()->SetEchoF(1);
  977.     te()->Verify();
  978.     return 1;
  979.   }
  980.  
  981. // =============================>>> vSeeCI::yankfile   <<<=========================
  982.   int vSeeCI::yankfile(long cnt)
  983.   {     // yank file to or from save bufer
  984.  
  985.     long l, lend;
  986.  
  987.     int old_ef = te()->GetEdState().echof;       // remember state of echo flag
  988.  
  989.     char buff[MAX_LINE+2];
  990.     vFileSelect fsel(cmdWin());
  991.  
  992.     if (cnt < 0)        // write save buffer
  993.       {
  994.     buff[0] = 0;
  995.     int ians = fsel.FileSelectSave("Write save buffer to file",
  996.         buff, MAX_LINE, filter, filterIndex);
  997.     if (!ians)
  998.         return 0;
  999.  
  1000.     ofstream fout(buff);        // open the file to yank
  1001.      if (!fout)
  1002.         return 0;
  1003.  
  1004.     for (long lx = 0; lx < nxtsav ; ++lx)
  1005.         fout << _SaveBuff[lx] << endl;
  1006.     fout.close();
  1007.     return 1;
  1008.       }
  1009.     else
  1010.       {
  1011.     buff[0] = 0;
  1012.     int ians = fsel.FileSelect("Yank file to save buffer",
  1013.         buff, MAX_LINE, filter, filterIndex);
  1014.     if (!ians)
  1015.         return 0;
  1016.  
  1017.     ifstream fin(buff);        // open the file to yank
  1018.      if (!fin)
  1019.         return 0;
  1020.  
  1021.         // Clear old save buffer - delete storage for lines
  1022.         for (long lx = 0 ; lx < nxtsav ; ++lx)  // copy old lines
  1023.         if (_SaveBuff[lx])
  1024.                 delete [] _SaveBuff[lx];    // free space
  1025.  
  1026.         slastl = savlen = nxtsav = 0;    /* reset these guys */
  1027.  
  1028.     while (fin.getline(buff,511))
  1029.       {
  1030.         if (nxtsav >= _maxSBLines)         // check for max lines
  1031.           {
  1032.         if (!reallocSaveBuff())
  1033.           {
  1034.             te()->ErrorMsg("File too big -- only partially read ");
  1035.             fin.close();
  1036.             return 0;
  1037.           }
  1038.           }
  1039.         // have a line to add
  1040.         char* cp = new char[strlen(buff) + 1];
  1041.         strcpy(cp, buff);
  1042.         _SaveBuff[nxtsav++] = cp;    // copy the line to buffer
  1043.  
  1044.       }
  1045.     fin.close();
  1046.       }
  1047.     return 1;
  1048.   }
  1049.  
  1050. #ifdef XXYYXX
  1051. //=============================>>> vSeeCI::ins_pat  <<<=============================
  1052. #ifdef ANSI_C
  1053.   int ins_pat(void)
  1054. #else
  1055.   int ins_pat()
  1056. #endif
  1057.   {
  1058.     char *chrp;
  1059.  
  1060.     if (!*pat_buff)
  1061.     return 0;
  1062.  
  1063.     for (chrp = pat_buff ; *chrp ; )    /* simply insert pattern buffer */
  1064.       {
  1065.     if (!ins_chr((int)*chrp++))    /* make sure it works */
  1066.         return 0;
  1067.       }
  1068.  
  1069.     return 1;
  1070.   }
  1071. #endif
  1072.