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: }

Defined functions

adjust_markers defined in line 115; used 5 times
gap_left defined in line 41; used 2 times
gap_right defined in line 75; used 2 times
insert_before_markers defined in line 232; used 2 times
insert_char defined in line 189; used 2 times
make_gap defined in line 149; used 2 times
prepare_to_modify_buffer defined in line 303; used 4 times
Last modified: 1985-12-19
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1526
Valid CSS Valid XHTML 1.0 Strict