Annotation of 43BSDReno/contrib/emacs-18.55/src/insdel.c, revision 1.1

1.1     ! root        1: /* Buffer insertion/deletion and gap motion for GNU Emacs.
        !             2:    Copyright (C) 1985, 1986 Free Software Foundation, Inc.
        !             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:    Note that this can quit!  */
        !            29: 
        !            30: move_gap (pos)
        !            31:      int pos;
        !            32: {
        !            33:   if (bf_p2 != bf_gap + bf_p1)
        !            34:     abort ();
        !            35: 
        !            36:   if (pos <= bf_s1)
        !            37:     gap_left (pos);
        !            38:   else if (pos > bf_s1 + 1)
        !            39:     gap_right (pos);
        !            40: }
        !            41: 
        !            42: gap_left (pos)
        !            43:      register int pos;
        !            44: {
        !            45:   register unsigned char *to, *from;
        !            46:   register int i;
        !            47:   int new_s1;
        !            48: 
        !            49:   pos--;
        !            50: 
        !            51:   if (unchanged_modified == bf_modified)
        !            52:     {
        !            53:       beg_unchanged = pos;
        !            54:       end_unchanged = bf_s1 + bf_s2 - pos;
        !            55:     }
        !            56:   else
        !            57:     {
        !            58:       if (bf_s2 < end_unchanged)
        !            59:        end_unchanged = bf_s2;
        !            60:       if (pos < beg_unchanged)
        !            61:        beg_unchanged = pos;
        !            62:     }
        !            63: 
        !            64:   i = bf_s1 + 1;
        !            65:   to = &bf_p2[i];
        !            66:   from = &bf_p1[i];
        !            67:   new_s1 = bf_s1;
        !            68: 
        !            69:   /* Now copy the characters.  To move the gap down,
        !            70:      copy characters up.  */
        !            71: 
        !            72:   while (1)
        !            73:     {
        !            74:       /* I gets number of characters left to copy.  */
        !            75:       i = new_s1 - pos;
        !            76:       if (i == 0)
        !            77:        break;
        !            78:       /* If a quit is requested, stop copying now.
        !            79:         Change POS to be where we have actually moved the gap to.  */
        !            80:       if (QUITP)
        !            81:        {
        !            82:          pos = new_s1;
        !            83:          break;
        !            84:        }
        !            85:       /* Move at most 32000 chars before checking again for a quit.  */
        !            86:       if (i > 32000)
        !            87:        i = 32000;
        !            88:       new_s1 -= i;
        !            89:       while (--i >= 0)
        !            90:        *--to = *--from;
        !            91:     }
        !            92: 
        !            93:   /* Adjust markers, and buffer data structure, to put the gap at POS.
        !            94:      POS is where the loop above stopped, which may be what was specified
        !            95:      or may be where a quit was detected.  */
        !            96:   adjust_markers (pos + 1, bf_s1 + 1, bf_gap);
        !            97:   bf_s2 += bf_s1 - pos;
        !            98:   bf_s1 = pos;
        !            99:   QUIT;
        !           100: }
        !           101: 
        !           102: gap_right (pos)
        !           103:      register int pos;
        !           104: {
        !           105:   register unsigned char *to, *from;
        !           106:   register int i;
        !           107:   int new_s1;
        !           108: 
        !           109:   pos--;
        !           110: 
        !           111:   if (unchanged_modified == bf_modified)
        !           112:     {
        !           113:       beg_unchanged = pos;
        !           114:       end_unchanged = bf_s1 + bf_s2 - pos;
        !           115:     }
        !           116:   else
        !           117:     {
        !           118:       if (bf_s1 + bf_s2 - pos < end_unchanged)
        !           119:        end_unchanged = bf_s1 + bf_s2 - pos;
        !           120:       if (bf_s1 < beg_unchanged)
        !           121:        beg_unchanged = bf_s1;
        !           122:     }
        !           123: 
        !           124:   i = bf_s1 + 1;
        !           125:   from = &bf_p2[i];
        !           126:   to = &bf_p1[i];
        !           127:   new_s1 = bf_s1;
        !           128: 
        !           129:   /* Now copy the characters.  To move the gap up,
        !           130:      copy characters down.  */
        !           131: 
        !           132:   while (1)
        !           133:     {
        !           134:       /* I gets number of characters left to copy.  */
        !           135:       i = pos - new_s1;
        !           136:       if (i == 0)
        !           137:        break;
        !           138:       /* If a quit is requested, stop copying now.
        !           139:         Change POS to be where we have actually moved the gap to.  */
        !           140:       if (QUITP)
        !           141:        {
        !           142:          pos = new_s1;
        !           143:          break;
        !           144:        }
        !           145:       /* Move at most 32000 chars before checking again for a quit.  */
        !           146:       if (i > 32000)
        !           147:        i = 32000;
        !           148:       new_s1 += i;
        !           149:       while (--i >= 0)
        !           150:        *to++ = *from++;
        !           151:     }
        !           152: 
        !           153:   adjust_markers (bf_s1 + bf_gap + 1, pos + bf_gap + 1, - bf_gap);
        !           154:   bf_s2 += bf_s1 - pos;
        !           155:   bf_s1 = pos;
        !           156:   QUIT;
        !           157: }
        !           158: 
        !           159: /* Add `amount' to the position of every marker in the current buffer
        !           160:    whose current position is between `from' (exclusive) and `to' (inclusive).
        !           161:    Also, any markers past the outside of that interval, in the direction
        !           162:    of adjustment, are first moved back to the near end of the interval
        !           163:    and then adjusted by `amount'.  */
        !           164: 
        !           165: adjust_markers (from, to, amount)
        !           166:      register int from, to, amount;
        !           167: {
        !           168:   Lisp_Object marker;
        !           169:   register struct Lisp_Marker *m;
        !           170:   register int mpos;
        !           171: 
        !           172:   marker = bf_cur->markers;
        !           173: 
        !           174:   while (!NULL (marker))
        !           175:     {
        !           176:       m = XMARKER (marker);
        !           177:       mpos = m->bufpos;
        !           178:       if (amount > 0)
        !           179:        {
        !           180:          if (mpos > to && mpos < to + amount)
        !           181:            mpos = to + amount;
        !           182:        }
        !           183:       else
        !           184:        {
        !           185:          if (mpos > from + amount && mpos <= from)
        !           186:            mpos = from + amount;
        !           187:        }
        !           188:       if (mpos > from && mpos <= to)
        !           189:        mpos += amount;
        !           190:       if (m->bufpos != mpos)
        !           191:        m->bufpos = mpos, m->modified++;
        !           192:       marker = m->chain;
        !           193:     }
        !           194: }
        !           195: 
        !           196: /* make sure that the gap in the current buffer is at least k
        !           197:    characters wide */
        !           198: 
        !           199: make_gap (k)
        !           200:      int k;
        !           201: {
        !           202:   register unsigned char *p1, *p2, *lim;
        !           203: 
        !           204:   if (bf_gap >= k)
        !           205:     return;
        !           206: 
        !           207:   k += 2000;                   /* Get more than just enough */
        !           208: 
        !           209:   p1 = (unsigned char *) realloc (bf_p1 + 1, bf_s1 + bf_s2 + k);
        !           210:   if (p1 == 0)
        !           211:     memory_full ();
        !           212: 
        !           213:   k -= bf_gap;                 /* Amount of increase.  */
        !           214: 
        !           215:   /* Record new location of text */
        !           216:   bf_p1 = p1 - 1;
        !           217: 
        !           218:   /* Transfer the new free space from the end to the gap
        !           219:      by shifting the second segment upward */
        !           220:   p2 = bf_p1 + 1 + bf_s1 + bf_s2 + bf_gap;
        !           221:   p1 = p2 + k;
        !           222:   lim = p2 - bf_s2;
        !           223:   while (lim < p2)
        !           224:     *--p1 = *--p2;
        !           225: 
        !           226:   /* Finish updating text location data */
        !           227:   bf_gap += k;
        !           228:   bf_p2 = bf_p1 + bf_gap;
        !           229: 
        !           230:   /* Don't wait for next SetBfp; make it permanent now. */
        !           231:   bf_cur->text = bf_text;
        !           232: 
        !           233:   /* adjust markers */
        !           234:   adjust_markers (bf_s1 + 1, bf_s1 + bf_s2 + bf_gap + 1, k);
        !           235: }
        !           236: 
        !           237: /* Insert the character c before point */
        !           238: 
        !           239: insert_char (c)
        !           240:      unsigned char c;
        !           241: {
        !           242:   InsCStr (&c, 1);
        !           243: }
        !           244: 
        !           245: /* Insert the null-terminated string s before point */
        !           246: 
        !           247: InsStr (s)
        !           248:      char *s;
        !           249: {
        !           250:   InsCStr (s, strlen (s));
        !           251: }
        !           252: 
        !           253: /* Insert a string of specified length before point */
        !           254: 
        !           255: InsCStr (string, length)
        !           256:      register unsigned char *string;
        !           257:      register length;
        !           258: {
        !           259:   if (length<1)
        !           260:     return;
        !           261: 
        !           262:   prepare_to_modify_buffer ();
        !           263: 
        !           264:   if (point != bf_s1 + 1)
        !           265:     move_gap (point);
        !           266:   if (bf_gap < length)
        !           267:     make_gap (length);
        !           268: 
        !           269:   record_insert (point, length);
        !           270:   bf_modified++;
        !           271: 
        !           272:   bcopy (string, bf_p1 + point, length);
        !           273: 
        !           274:   bf_gap -= length;
        !           275:   bf_p2 -= length;
        !           276:   bf_s1 += length;
        !           277:   point += length;
        !           278: }
        !           279: 
        !           280: /* like InsCStr except that all markers pointing at the place where
        !           281:    the insertion happens are adjusted to point after it.  */
        !           282: 
        !           283: insert_before_markers (string, length)
        !           284:      unsigned char *string;
        !           285:      register int length;
        !           286: {
        !           287:   register int opoint = point;
        !           288:   InsCStr (string, length);
        !           289:   adjust_markers (opoint - 1, opoint, length);
        !           290: }
        !           291: 
        !           292: /* Delete characters in current buffer
        !           293:   from `from' up to (but not incl) `to' */
        !           294: 
        !           295: del_range (from, to)
        !           296:      register int from, to;
        !           297: {
        !           298:   register int numdel;
        !           299: 
        !           300:   /* Make args be valid */
        !           301:   if (from < FirstCharacter)
        !           302:     from = FirstCharacter;
        !           303:   if (to > NumCharacters)
        !           304:     to = NumCharacters + 1;
        !           305: 
        !           306:   if ((numdel = to - from) <= 0)
        !           307:     return;
        !           308: 
        !           309:   /* Make sure the gap is somewhere in or next to what we are deleting */
        !           310:   if (from - 1 > bf_s1)
        !           311:     gap_right (from);
        !           312:   if (to - 1 < bf_s1)
        !           313:     gap_left (to);
        !           314: 
        !           315:   prepare_to_modify_buffer ();
        !           316:   record_delete (from, numdel);
        !           317:   bf_modified++;
        !           318: 
        !           319:   /* Relocate point as if it were a marker.  */
        !           320:   if (from < point)
        !           321:     {
        !           322:       if (point < to)
        !           323:        point = from;
        !           324:       else
        !           325:        point -= numdel;
        !           326:     }
        !           327: 
        !           328:   /* Relocate all markers pointing into the new, larger gap
        !           329:      to point at the end of the text before the gap.  */
        !           330:   adjust_markers (to + bf_gap, to + bf_gap, - numdel - bf_gap);
        !           331: 
        !           332:   bf_gap += numdel;
        !           333:   bf_p2 += numdel;
        !           334:   bf_s2 -= to - 1 - bf_s1;
        !           335:   bf_s1 = from - 1;
        !           336: 
        !           337:   if (bf_s1 < beg_unchanged)
        !           338:     beg_unchanged = bf_s1;
        !           339:   if (bf_s2 < end_unchanged)
        !           340:     end_unchanged = bf_s2;
        !           341: }
        !           342: 
        !           343: modify_region (start, end)
        !           344:      int start, end;
        !           345: {
        !           346:   prepare_to_modify_buffer ();
        !           347:   if (start - 1 < beg_unchanged || unchanged_modified == bf_modified)
        !           348:     beg_unchanged = start - 1;
        !           349:   if (bf_s1 + bf_s2 + 1 - end < end_unchanged
        !           350:       || unchanged_modified == bf_modified)
        !           351:     end_unchanged = bf_s1 + bf_s2 + 1 - end;
        !           352:   bf_modified++;
        !           353: }
        !           354: 
        !           355: prepare_to_modify_buffer ()
        !           356: {
        !           357:   if (!NULL (bf_cur->read_only))
        !           358:     Fbarf_if_buffer_read_only();
        !           359: 
        !           360: #ifdef CLASH_DETECTION
        !           361:   if (!NULL (bf_cur->filename)
        !           362:       && bf_cur->save_modified >= bf_modified)
        !           363:     lock_file (bf_cur->filename);
        !           364: #else
        !           365:   /* At least warn if this file has changed on disk since it was visited.  */
        !           366:   if (!NULL (bf_cur->filename)
        !           367:       && bf_cur->save_modified >= bf_modified
        !           368:       && NULL (Fverify_visited_file_modtime (Fcurrent_buffer ()))
        !           369:       && !NULL (Ffile_exists_p (bf_cur->filename)))
        !           370:     call1 (intern ("ask-user-about-supersession-threat"),
        !           371:           bf_cur->filename);
        !           372: #endif /* not CLASH_DETECTION */
        !           373: }

unix.superglobalmegacorp.com

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