Annotation of 43BSD/contrib/emacs/src/insdel.c, revision 1.1.1.1

1.1       root        1: /* Buffer insertion/deletion and gap motion for GNU Emacs.
                      2:    Copyright (C) 1985 Richard M. Stallman.
                      3: 
                      4: This file is part of GNU Emacs.
                      5: 
                      6: GNU Emacs is distributed in the hope that it will be useful,
                      7: but WITHOUT ANY WARRANTY.  No author or distributor
                      8: accepts responsibility to anyone for the consequences of using it
                      9: or for whether it serves any particular purpose or works at all,
                     10: unless he says so in writing.  Refer to the GNU Emacs General Public
                     11: License for full details.
                     12: 
                     13: Everyone is granted permission to copy, modify and redistribute
                     14: GNU Emacs, but only under the conditions described in the
                     15: GNU Emacs General Public License.   A copy of this license is
                     16: supposed to have been given to you along with GNU Emacs so you
                     17: can know your rights and responsibilities.  It should be in a
                     18: file named COPYING.  Among other things, the copyright notice
                     19: and this notice must be preserved on all copies.  */
                     20: 
                     21: 
                     22: #include "config.h"
                     23: #include "lisp.h"
                     24: #include "buffer.h"
                     25: #include "window.h"
                     26: 
                     27: /* Move gap to position `pos'. */
                     28: 
                     29: GapTo (pos)
                     30:      int pos;
                     31: {
                     32:   if (bf_p2 != bf_gap + bf_p1)
                     33:     abort ();
                     34: 
                     35:   if (pos <= bf_s1)
                     36:     gap_left (pos);
                     37:   else if (pos > bf_s1 + 1)
                     38:     gap_right (pos);
                     39: }
                     40: 
                     41: gap_left (pos)
                     42:      register int pos;
                     43: {
                     44:   register unsigned char *to, *from;
                     45:   register int i;
                     46: 
                     47:   pos--;
                     48: 
                     49:   if (unchanged_modified == bf_modified)
                     50:     {
                     51:       beg_unchanged = pos;
                     52:       end_unchanged = bf_s1 + bf_s2 - pos;
                     53:     }
                     54:   else
                     55:     {
                     56:       if (bf_s2 < end_unchanged)
                     57:        end_unchanged = bf_s2;
                     58:       if (pos < beg_unchanged)
                     59:        beg_unchanged = pos;
                     60:     }
                     61: 
                     62:   adjust_markers (pos + 1, bf_s1 + 1, bf_gap);
                     63: 
                     64:   to = bf_p2;
                     65:   from = bf_p1;
                     66: 
                     67:   i = bf_s1 + 1;
                     68:   while (--i > pos)
                     69:     to[i] = from[i];
                     70: 
                     71:   bf_s2 += bf_s1 - pos;
                     72:   bf_s1 = pos;
                     73: }
                     74: 
                     75: gap_right (pos)
                     76:      register int pos;
                     77: {
                     78:   register unsigned char *to, *from;
                     79:   register int i;
                     80: 
                     81:   pos--;
                     82: 
                     83:   if (unchanged_modified == bf_modified)
                     84:     {
                     85:       beg_unchanged = pos;
                     86:       end_unchanged = bf_s1 + bf_s2 - pos;
                     87:     }
                     88:   else
                     89:     {
                     90:       if (bf_s1 + bf_s2 - pos < end_unchanged)
                     91:        end_unchanged = bf_s1 + bf_s2 - pos;
                     92:       if (bf_s1 < beg_unchanged)
                     93:        beg_unchanged = bf_s1;
                     94:     }
                     95: 
                     96:   adjust_markers (bf_s1 + bf_gap + 1, pos + bf_gap + 1, - bf_gap);
                     97: 
                     98:   from = bf_p2;
                     99:   to = bf_p1;
                    100: 
                    101:   i = bf_s1;
                    102:   while (++i <= pos)
                    103:     to[i] = from[i];
                    104: 
                    105:   bf_s2 += bf_s1 - pos;
                    106:   bf_s1 = pos;
                    107: }
                    108: 
                    109: /* Add `amount' to the position of every marker in the current buffer
                    110:    whose current position is between `from' (exclusive) and `to' (inclusive).
                    111:    Also, any markers past the outside of that interval, in the direction
                    112:    of adjustment, are first moved back to the near end of the interval
                    113:    and then adjusted by `amount'.  */
                    114: 
                    115: adjust_markers (from, to, amount)
                    116:      register int from, to, amount;
                    117: {
                    118:   Lisp_Object marker;
                    119:   register struct Lisp_Marker *m;
                    120:   register int mpos;
                    121: 
                    122:   marker = bf_cur->markers;
                    123: 
                    124:   while (!NULL (marker))
                    125:     {
                    126:       m = XMARKER (marker);
                    127:       mpos = m->bufpos;
                    128:       if (amount > 0)
                    129:        {
                    130:          if (mpos > to && mpos < to + amount)
                    131:            mpos = to + amount;
                    132:        }
                    133:       else
                    134:        {
                    135:          if (mpos > from + amount && mpos <= from)
                    136:            mpos = from + amount;
                    137:        }
                    138:       if (mpos > from && mpos <= to)
                    139:        mpos += amount;
                    140:       if (m->bufpos != mpos)
                    141:        m->bufpos = mpos, m->modified++;
                    142:       marker = m->chain;
                    143:     }
                    144: }
                    145: 
                    146: /* make sure that the gap in the current buffer is at least k
                    147:    characters wide */
                    148: 
                    149: make_gap (k)
                    150:      int k;
                    151: {
                    152:   register unsigned char *p1, *p2, *lim;
                    153: 
                    154:   if (bf_gap >= k)
                    155:     return;
                    156: 
                    157:   k += 2000;                   /* Get more than just enough */
                    158: 
                    159:   p1 = (unsigned char *) realloc (bf_p1 + 1, bf_s1 + bf_s2 + k);
                    160:   if (p1 == 0)
                    161:     memory_full ();
                    162: 
                    163:   k -= bf_gap;                 /* Amount of increase.  */
                    164: 
                    165:   /* Record new location of text */
                    166:   bf_p1 = p1 - 1;
                    167: 
                    168:   /* Transfer the new free space from the end to the gap
                    169:      by shifting the second segment upward */
                    170:   p2 = bf_p1 + 1 + bf_s1 + bf_s2 + bf_gap;
                    171:   p1 = p2 + k;
                    172:   lim = p2 - bf_s2;
                    173:   while (lim < p2)
                    174:       *--p1 = *--p2;
                    175: 
                    176:   /* Finish updating text location data */
                    177:   bf_gap += k;
                    178:   bf_p2 = bf_p1 + bf_gap;
                    179: 
                    180:   /* Don't wait for next SetBfp; make it permanent now. */
                    181:   bf_cur->text = bf_text;
                    182: 
                    183:   /* adjust markers */
                    184:   adjust_markers (bf_s1 + 1, bf_s1 + bf_s2 + bf_gap + 1, k);
                    185: }
                    186: 
                    187: /* Insert the character c before point */
                    188: 
                    189: insert_char (c)
                    190:      unsigned char c;
                    191: {
                    192:   InsCStr (&c, 1);
                    193: }
                    194: 
                    195: /* Insert the null-terminated string s before point */
                    196: 
                    197: InsStr (s)
                    198:      char *s;
                    199: {
                    200:   InsCStr (s, strlen (s));
                    201: }
                    202: 
                    203: /* Insert a string of specified length before point */
                    204: 
                    205: InsCStr (string, length)
                    206:      register unsigned char *string;
                    207:      register length;
                    208: {
                    209:   if (length<1)
                    210:     return;
                    211: 
                    212:   prepare_to_modify_buffer ();
                    213:   RecordInsert (point, length);
                    214:   bf_modified++;
                    215: 
                    216:   if (point != bf_s1 + 1)
                    217:     GapTo (point);
                    218:   if (bf_gap < length)
                    219:     make_gap (length);
                    220: 
                    221:   bcopy (string, bf_p1 + point, length);
                    222: 
                    223:   bf_gap -= length;
                    224:   bf_p2 -= length;
                    225:   bf_s1 += length;
                    226:   point += length;
                    227: }
                    228: 
                    229: /* like InsCStr except that all markers pointing at the place where
                    230:    the insertion happens are adjusted to point after it.  */
                    231: 
                    232: insert_before_markers (string, length)
                    233:      unsigned char *string;
                    234:      register int length;
                    235: {
                    236:   register int opoint = point;
                    237:   InsCStr (string, length);
                    238:   adjust_markers (opoint - 1, opoint, length);
                    239: }
                    240: 
                    241: /* Delete characters in current buffer
                    242:   from `from' up to (but not incl) `to' */
                    243: 
                    244: del_range (from, to)
                    245:      register int from, to;
                    246: {
                    247:   register int numdel;
                    248: 
                    249:   /* Make args be valid */
                    250:   if (from < FirstCharacter)
                    251:     from = FirstCharacter;
                    252:   if (to > NumCharacters)
                    253:     to = NumCharacters + 1;
                    254: 
                    255:   if ((numdel = to - from) <= 0)
                    256:     return;
                    257: 
                    258:   if (from < point)
                    259:     {
                    260:       if (point < to)
                    261:        point = from;
                    262:       else
                    263:        point -= numdel;
                    264:     }
                    265: 
                    266:   /* Make sure the gap is somewhere in or next to what we are deleting */
                    267:   if (from - 1 > bf_s1)
                    268:     gap_right (from);
                    269:   if (to - 1 < bf_s1)
                    270:     gap_left (to);
                    271: 
                    272:   prepare_to_modify_buffer ();
                    273:   RecordDelete (from, numdel);
                    274:   bf_modified++;
                    275: 
                    276:   /* All markers pointing between from and to, inclusive,
                    277:      should now point at from.  */
                    278:   adjust_markers (to, to, -numdel);
                    279: 
                    280:   bf_gap += numdel;
                    281:   bf_p2 += numdel;
                    282:   bf_s2 -= to - 1 - bf_s1;
                    283:   bf_s1 = from - 1;
                    284: 
                    285:   if (bf_s1 < beg_unchanged)
                    286:     beg_unchanged = bf_s1;
                    287:   if (bf_s2 < end_unchanged)
                    288:     end_unchanged = bf_s2;
                    289: }
                    290: 
                    291: modify_region (start, end)
                    292:      int start, end;
                    293: {
                    294:   prepare_to_modify_buffer ();
                    295:   if (start - 1 < beg_unchanged || unchanged_modified == bf_modified)
                    296:     beg_unchanged = start - 1;
                    297:   if (bf_s1 + bf_s2 + 1 - end < end_unchanged
                    298:       || unchanged_modified == bf_modified)
                    299:     end_unchanged = bf_s1 + bf_s2 + 1 - end;
                    300:   bf_modified++;
                    301: }
                    302: 
                    303: prepare_to_modify_buffer ()
                    304: {
                    305:   if (!NULL (bf_cur->read_only))
                    306:     Fbarf_if_buffer_read_only();
                    307: 
                    308: #ifdef CLASH_DETECTION
                    309:   if (!NULL (bf_cur->filename)
                    310:       && bf_cur->save_modified >= bf_modified)
                    311:     lock_file (bf_cur->filename);
                    312: #endif /* CLASH_DETECTION */
                    313: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.