home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 424_01 / ed_157 / insert.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-27  |  5.4 KB  |  209 lines

  1. /*
  2.  * Copyright (C) 1992 by Rush Record
  3.  * Copyright (C) 1993 by Charles Sandmann (sandmann@clio.rice.edu)
  4.  * 
  5.  * This file is part of ED.
  6.  * 
  7.  * ED is free software; you can redistribute it and/or modify it under the terms
  8.  * of the GNU General Public License as published by the Free Software Foundation.
  9.  * 
  10.  * ED is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  11.  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  12.  * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
  13.  * 
  14.  * You should have received a copy of the GNU General Public License along with ED
  15.  * (see the file COPYING).  If not, write to the Free Software Foundation, 675
  16.  * Mass Ave, Cambridge, MA 02139, USA.
  17.  */
  18. #include "opsys.h"
  19.  
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22.  
  23. #include "handy.h"
  24. #include "rec.h"
  25. #include "window.h"
  26. #include "ed_dec.h"
  27. #include "buffer.h"
  28.  
  29. static Char boxmode = 0;
  30.  
  31. /******************************************************************************\
  32. |Routine: insert_box
  33. |Callby: edit
  34. |Purpose: A one-shot to enable box paste.
  35. |Arguments:
  36. |    none
  37. \******************************************************************************/
  38. void insert_box()
  39. {
  40.     boxmode = 1;
  41. }
  42.  
  43. /******************************************************************************\
  44. |Routine: insert
  45. |Callby: carriage_ret cfrendly command edit include_file openline word_fill
  46. |Purpose: Handles insertion of new data at the current position.
  47. |Arguments:
  48. |    buf is the buffer containing the record(s) to be inserted.
  49. \******************************************************************************/
  50. void insert(buf)
  51. register buf_ptr buf;
  52. {
  53.     static Int recursing = 0;
  54.     register Int i,j,fixeob,column;
  55.     rec_ptr r,new;
  56.     register rec_ptr b;
  57.     register Char c;
  58.  
  59.     if(!buf->nrecs)    /* ignore attempts to insert empty buffers */
  60.         return;
  61.     if(buf->nrecs == 1)    /* special handling for simple insertions */
  62.     {
  63.         if(CURREC == BASE && buf->last->length > 0)
  64.         {
  65.             carriage_return(1);
  66.             left_arrow(1);
  67.         }
  68.         if(OVERSTRIKE)
  69.             rec_overstrike(&CURREC,CURBYT,buf->first->length,buf->first->data);
  70.         else
  71.             rec_insert(&CURREC,CURBYT,buf->first->length,buf->first->data);
  72.         paint(CURROW,CURROW,FIRSTCOL);
  73.         if(buf->direction == 1)
  74.         {
  75.             CURBYT += buf->first->length;
  76.             WANTCOL = CURCOL = get_column(CURREC,CURBYT);
  77.             if(puttest() && CLOSE_PARENS)
  78.             {
  79.                 c = buf->first->data[buf->first->length - 1];
  80.                 for(i = 0;i < PAREN_STRING_LENGTH;i++)
  81.                     if(c == PAREN_STRING[i])
  82.                     {
  83.                         if(i & 1)
  84.                             match_paren(PAREN_STRING[i - 1],PAREN_STRING[i],-1);
  85.                         else
  86.                             match_paren(PAREN_STRING[i],PAREN_STRING[i + 1],1);
  87.                         break;
  88.                     }
  89.             }
  90.         }
  91.         return;
  92.     }
  93.     if((boxmode || OVERSTRIKE) && !recursing)
  94.     {
  95.         recursing = 1;
  96.         if(CURREC == BASE)
  97.         {
  98.             carriage_return(1);
  99.             left_arrow(1);
  100.         }
  101.         column = get_column(CURREC,CURBYT);
  102.         i = get_colbyt(CURREC,column - 1) + 1;    /* this converts the current record, so we can get the real column number */
  103.         column = get_column(CURREC,i);
  104.         for(i = buf->nrecs,r = CURREC;i && (r != BASE);i--,r = r->next);    /* check whether we need to extend the file to make room */
  105.         if(i)
  106.         {
  107.             if((j = buf->nrecs - i))
  108.                 down_arrow(j);
  109.             carriage_return(i);
  110.             up_arrow(buf->nrecs);
  111.             if(column > 1)
  112.                 right_arrow(column - 1);
  113.         }
  114.         if(boxmode)
  115.             for(r = CURREC,b = buf->first,i = buf->nrecs;i--;b = b->next,r = r->next)
  116.             {
  117.                 j = get_colbyt(r,column - 1) + 1;
  118.                 if(OVERSTRIKE)
  119.                     rec_overstrike(&r,j,b->length,b->data);
  120.                 else
  121.                     rec_insert(&r,j,b->length,b->data);
  122.             }
  123.         else
  124.             for(r = CURREC,b = buf->first,i = buf->nrecs;i--;b = b->next,r = r->next)
  125.             {
  126.                 j = get_colbyt(r,column - 1) + 1;
  127.                 if(r == CURREC)
  128.                     rec_overstrike(&r,j,b->length,b->data);
  129.                 else
  130.                     rec_overstrike(&r,0,b->length,b->data);
  131.             }
  132.         if((i = CURROW + buf->nrecs - 1) > BOTROW)
  133.             i = BOTROW;
  134.         paint(CURROW,i,FIRSTCOL);
  135.         recursing = 0;
  136.         if(buf->direction == 1 && !boxmode)
  137.         {
  138.             for(i = buf->nrecs - 1;i--;CURREC = CURREC->next,CURROW++);
  139.             CURBYT = max(0,buf->last->length - 1);
  140.             if(boxmode)
  141.                 CURBYT += j;
  142.             fix_scroll();
  143.         }
  144.         boxmode = 0;
  145.         return;
  146.     }
  147. /* non-box-mode, regular multiline insertion */
  148.     rec_split(&CURREC,CURBYT);    /* split the current record in two */
  149.     if(CURREC->next == BASE && buf->last->length > 0)
  150.     {
  151.         carriage_return(1);
  152.         left_arrow(1);
  153.         fixeob = 1;
  154.     }
  155.     else
  156.         fixeob = 0;
  157.     rec_insert(&CURREC,CURBYT,buf->first->length,buf->first->data);    /* append the first insert record to the first half */
  158.     r = CURREC;    /* all records will be inserted following to this one */
  159.     b = buf->first;
  160.     for(i = 2;i < buf->nrecs;i++)    /* insert all complete records */
  161.     {
  162.         b = b->next;
  163.         rec_copy(b,&new);
  164.         insq(new,r);
  165.         r = new;
  166.     }
  167.     if((r = r->next) != BASE)    /* point at the second half of the split record */
  168.         rec_insert(&r,0,buf->last->length,buf->last->data);
  169.     if(TOPREC == BASE)
  170.         TOPREC = BASE->next;
  171.     if(buf->direction == -1)
  172.     {
  173.         for(r = CURREC,i = CURROW;i < BOTROW && r != BASE;i++,r = r->next);
  174.         if(i == BOTROW)
  175.             BOTREC = r;
  176.         else
  177.             BOTREC = 0;
  178.         ins_line(buf->nrecs - 1);
  179.         paint(CURROW,BOTROW,FIRSTCOL);
  180.     }
  181.     else
  182.     {
  183.         CURREC = r;
  184.         CURBYT = buf->last->length;
  185.         for(i = CURROW;i > TOPROW;i--,r = r->prev);
  186.         TOPREC = r;
  187.         if(CURROW > TOPROW)
  188.         {
  189.             marge(TOPROW,CURROW);
  190.             move(TOPROW,1);
  191.             del_line(buf->nrecs - 1);
  192.             marge(TOPROW,BOTROW);
  193.         }
  194.         paint(TOPROW,CURROW,FIRSTCOL);
  195.     }
  196.     CURCOL = get_column(CURREC,CURBYT);
  197.     if(fixeob)
  198.     {
  199.         for(i = TOPROW,r = TOPREC;i <= BOTROW,r != BASE;i++,r = r->next);
  200.         if(r == BASE)
  201.         {
  202.             move(i,1);
  203.             eob();
  204.         }
  205.     }
  206.     fix_scroll();
  207. }
  208.  
  209.