home *** CD-ROM | disk | FTP | other *** search
/ Best Objectech Shareware Selections / UNTITLED.iso / boss / word / text / 019 / ins.c < prev    next >
C/C++ Source or Header  |  1993-01-19  |  5KB  |  254 lines

  1. /*
  2.  *  Copyright (c) 1992 John E. Davis  (davis@amy.tch.harvard.edu)
  3.  *  All Rights Reserved.
  4.  */
  5. #include <stdio.h>
  6. #include "buffer.h"
  7. #include "ins.h"
  8. #include "line.h"
  9. #include "screen.h"
  10. #include "window.h"
  11. #include "misc.h"
  12. #include "paste.h"
  13. #include "vterm.h"
  14.  
  15. void update_generic_marks(Mark *m, int type, int n)
  16. {
  17.     if (m == NULL) return;
  18.       /* called by line deletion routines */
  19.     if (type == LDELETE) while(m != NULL)
  20.       {
  21.           if (CLine == m->line)
  22.             {
  23.                 if (CLine->prev != NULL)
  24.                   m->line = CLine->prev;
  25.                 else m->line = CBuf->beg;
  26.                 m->point = 0;
  27.             }
  28.           m = m->next;
  29.       }
  30.     else if (type == CINSERT) while(m != NULL)
  31.       {
  32.           if ((m->line == CLine) && (m->point > Point))
  33.             {
  34.                 m->point += n;
  35.             }
  36.           m = m->next;
  37.       }
  38.     else if (type == CDELETE) while(m != NULL)
  39.       {
  40.           if ((m->line == CLine) && (m->point > Point))
  41.             {
  42.            m->point -= n;
  43.            if (m->point < Point) m->point = Point;
  44.             }
  45.           m = m->next;
  46.       }
  47.     else if (type == NLINSERT) while(m != NULL)
  48.       {
  49.      /* This is a bit controversial if the mark corresponds to Window->beg.
  50.         In this case, Window beg gets shifted if Point = 0.  */
  51.           if ((m->line == CLine) && (m->point >= Point))
  52.             {
  53.                 m->line = CLine->next;
  54.                 m->point -= Point;
  55.                 if (m->point > m->line->len) m->point = m->line->len;
  56.             }
  57.           m = m->next;
  58.       }
  59.     else if (type == NLDELETE) while(m != NULL)
  60.       {
  61.           if (m->line == CLine)
  62.             {
  63.                 m->line = CLine->prev;
  64.                 m->point += Point;
  65.             }
  66.           m = m->next;
  67.       }
  68. }
  69.  
  70. void update_marks(int type, int n)
  71. {
  72.    Window_Type *w;
  73.  
  74.    Cursor_Motion = 0;
  75.    mark_buffer_modified(&Number_One);
  76.  
  77.    update_generic_marks(CBuf->spots, type, n);
  78.    update_generic_marks(CBuf->marks, type, n);
  79.  
  80.    w = Window;
  81.    do
  82.      {
  83.     if (w->buffer == CBuf)
  84.       {
  85.          update_generic_marks(&(w->mark), type, n);
  86.          update_generic_marks(&(w->beg), type, n);
  87.       }
  88.  
  89.     w = w->next;
  90.      }
  91.    while(w != Window);
  92.  
  93.    register_change(type);
  94. }
  95.  
  96. void ins(char c)
  97. {
  98.     unsigned char *p, *p1;
  99.  
  100.     if (CLine == NULL)
  101.       {
  102.           exit_error("ins: CLine is NULL\n");
  103.       }
  104.  
  105.     if (CLine->space <= CLine->len + 1)
  106.       {
  107.           remake_line(CLine->space + 25);
  108.       }
  109.  
  110.     p = CLine->data + Point;
  111.     if (Point < CLine->len)
  112.       {
  113.           p1 = CLine->data + (CLine->len - 1);
  114.           while(p1 >= p)
  115.             {
  116.                 *(p1 + 1) = *p1;
  117.                 p1--;
  118.             }
  119.       }
  120.     *p = c;
  121.     CLine->len += 1;
  122.     update_marks(CINSERT,1);
  123.     Point++;
  124. }
  125.  
  126. void del()
  127. {
  128.     unsigned char *p, *p1;
  129.  
  130.     if (eobp())
  131.       {
  132.           msg_error("End of Buffer.");
  133.           return;
  134.       }
  135.  
  136.     if (!eolp())
  137.       {
  138.           p = CLine->data + Point;
  139.           p1 = CLine->data + (CLine->len - 1);
  140.           while(p < p1)
  141.             {
  142.                 *p = *(p + 1);
  143.                 p++;
  144.             }
  145.           update_marks(CDELETE,1);
  146.           CLine->len -= 1;
  147.       }
  148.     else
  149.       {
  150.       if (CLine->len == 0)
  151.         {
  152.         exit_error("del(): empty line.");
  153.         }
  154.  
  155.           CLine->len -= 1;
  156.           update_marks(CDELETE,1);
  157.           splice_line();
  158.       }
  159. }
  160.  
  161. void ins_chars(unsigned char *s, int n)
  162. {
  163.     unsigned char *p1, *p;
  164.     int n1, n2;
  165.  
  166.     p1 = s;
  167.     n1 = 0;
  168.     /* count the number until a new line is reached */
  169.     while((n1 < n) && (*p1 != '\n'))
  170.       {
  171.           n1++;
  172.           p1++;
  173.       }
  174.  
  175.     if (CLine->space <= CLine->len + n1 + 1)
  176.       {
  177.           remake_line(CLine->space + n1 + 25);
  178.       }
  179.     /* shove n1 chars over to make space */
  180.     p = CLine->data + Point;
  181.     if (Point < CLine->len)   /* could be equal for last line of buffer */
  182.       {
  183.           p1 = CLine->data + CLine->len - 1;
  184.           while(p1 >= p)
  185.             {
  186.                 *(p1 + n1) = *p1;
  187.                 p1--;
  188.             }
  189.  
  190.       }
  191.     CLine->len += n1;
  192.     n2 = n1;
  193.     while (n2--) *p++ = *s++;
  194.     update_marks(CINSERT, n1);
  195.  
  196.     Point += n1;
  197.  
  198.     if (n1 < n)
  199.       {
  200.           split_line();
  201.           ins('\n');
  202.           CLine = CLine->next;
  203.           Point = 0;
  204.           ins_chars(s + 1, n - n1 - 1);
  205.       }
  206. }
  207.  
  208. void ins_char_n_times(char c, int n)
  209. {
  210.     char b[100], *p;
  211.     int n1;
  212.  
  213.     if (n == 0) return;
  214.     if (n > 100) n = 100;
  215.     p = b;
  216.     n1 = n;
  217.     while(n1--) *p++ = c;
  218.     ins_chars((unsigned char *) b, n);
  219. }
  220.  
  221. void insert_buffer(Buffer *b)
  222. {
  223.    Buffer *cb;
  224.  
  225.    if ((cb = CBuf) == b) return;
  226.  
  227.    switch_to_buffer(b);
  228.    push_spot();
  229.    bob(); push_mark();
  230.    eob();
  231.    copy_region_to_buffer(cb);
  232.    pop_spot();
  233.    switch_to_buffer(cb);
  234.  
  235.    touch_window();
  236. }
  237.  
  238. int No_Screen_Update;
  239.  
  240. void fast_ins(char ch)
  241. {
  242.     No_Screen_Update = 1;
  243.     vins(ch);
  244.     ins(ch);
  245. }
  246.  
  247. void fast_del()
  248. {
  249.     No_Screen_Update = 1;
  250.     vdel();
  251.     del();
  252. }
  253.  
  254.