1: /* Markers: examining, setting and killing.
   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: 
  26: /* Operations on markers. */
  27: 
  28: DEFUN ("marker-buffer", Fmarker_buffer, Smarker_buffer, 1, 1, 0,
  29:   "Return the buffer that MARKER points into, or nil if none.\n\
  30: Returns nil if MARKER points into a dead buffer.")
  31:   (marker)
  32:      Lisp_Object marker;
  33: {
  34:   Lisp_Object buf;
  35:   CHECK_MARKER (marker, 0);
  36:   if (XMARKER (marker)->buffer)
  37:     {
  38:       XSET (buf, Lisp_Buffer, XMARKER (marker)->buffer);
  39:       /* Return marker's buffer only if it is not dead.  */
  40:       if (!NULL (XBUFFER (buf)->name))
  41:     return buf;
  42:     }
  43:   return Qnil;
  44: }
  45: 
  46: DEFUN ("marker-position", Fmarker_position, Smarker_position, 1, 1, 0,
  47:   "Return the position MARKER points at, as a character number.")
  48:   (marker)
  49:      Lisp_Object marker;
  50: {
  51:   Lisp_Object pos;
  52:   int i;
  53:   struct buffer *buf;
  54:   struct buffer_text *text;
  55: 
  56:   CHECK_MARKER (marker, 0);
  57:   if (XMARKER (marker)->buffer)
  58:     {
  59:       buf = XMARKER (marker)->buffer;
  60:       i = XMARKER (marker)->bufpos;
  61:       text = (buf == bf_cur) ? &bf_text : &buf->text;
  62: 
  63:       if (i > text->size1 + text->gap + 1)
  64:     i -= text->gap;
  65:       else if (i > text->size1 + 1)
  66:     i = text->size1 + 1;
  67: 
  68:       if (i < 1 || i > text->size1 + text->size2 + 1)
  69:     abort ();
  70: 
  71:       XFASTINT (pos) = i;
  72:       return pos;
  73:     }
  74:   return Qnil;
  75: }
  76: 
  77: DEFUN ("set-marker", Fset_marker, Sset_marker, 2, 3, 0,
  78:   "Position MARKER before character number NUMBER in BUFFER.\n\
  79: BUFFER defaults to the current buffer.\n\
  80: If NUMBER is nil, makes marker point nowhere.\n\
  81: Then it no longer slows down editing in any buffer.\n\
  82: Returns MARKER.")
  83:   (marker, pos, buffer)
  84:      Lisp_Object marker, pos, buffer;
  85: {
  86:   int charno;
  87:   register struct buffer *b;
  88:   register struct buffer_text *text;
  89:   register struct Lisp_Marker *m;
  90: 
  91:   CHECK_MARKER (marker, 0);
  92:   if (NULL (pos))
  93:     {
  94:       unchain_marker (marker);
  95:       XMARKER (marker)->buffer = 0;
  96:       return marker;
  97:     }
  98: 
  99:   CHECK_NUMBER_COERCE_MARKER (pos, 1);
 100:   if (NULL (buffer))
 101:     b = bf_cur;
 102:   else
 103:     {
 104:       CHECK_BUFFER (buffer, 1);
 105:       b = XBUFFER (buffer);
 106:     }
 107: 
 108:   charno = XINT (pos);
 109:   m = XMARKER (marker);
 110: 
 111:   if (bf_cur == b)
 112:     text = &bf_text;
 113:   else
 114:     text = &b->text;
 115: 
 116:   if (charno < text->head_clip) charno = text->head_clip;
 117:   if (charno > text->size1 + text->size2 + 1 - text->tail_clip)
 118:     charno = text->size1 + text->size2 + 1 - text->tail_clip;
 119:   if (charno > text->size1 + 1) charno += text->gap;
 120:   m->bufpos = charno;
 121: 
 122:   if (m->buffer != b)
 123:     {
 124:       unchain_marker (marker);
 125:       m->chain = b->markers;
 126:       b->markers = marker;
 127:       m->buffer = b;
 128:     }
 129: 
 130:   return marker;
 131: }
 132: 
 133: /* This is called during garbage collection,
 134:  so we must be careful to ignore and preserve mark bits,
 135:  including those in chain fields of markers.  */
 136: 
 137: unchain_marker (marker)
 138:      Lisp_Object marker;
 139: {
 140:   Lisp_Object tail, prev, next;
 141:   register int omark;
 142: 
 143:   if (!XMARKER (marker)->buffer)
 144:     return;
 145: 
 146:   tail = XMARKER (marker)->buffer->markers;
 147:   prev = Qnil;
 148:   while (XSYMBOL (tail) != XSYMBOL (Qnil))
 149:     {
 150:       next = XMARKER (tail)->chain;
 151:       XUNMARK (next);
 152: 
 153:       if (XMARKER (marker) == XMARKER (tail))
 154:     {
 155:       if (NULL (prev))
 156:         XMARKER (marker)->buffer->markers = next;
 157:       else
 158:         {
 159:           omark = XMARKBIT (XMARKER (prev)->chain);
 160:           XMARKER (prev)->chain = next;
 161:           XSETMARKBIT (XMARKER (prev)->chain, omark);
 162:         }
 163:       break;
 164:     }
 165:       else
 166:     prev = tail;
 167:       tail = next;
 168:     }
 169:   XMARKER (marker)->buffer = 0;
 170: }
 171: 
 172: marker_position (marker)
 173:      Lisp_Object marker;
 174: {
 175:   register struct Lisp_Marker *m = XMARKER (marker);
 176:   register struct buffer *buf = m->buffer;
 177:   register int i = m->bufpos;
 178:   register struct buffer_text *text
 179:     = (buf == bf_cur) ? &bf_text : &buf->text;
 180: 
 181:   if (!buf)
 182:     error ("Marker does not point anywhere");
 183: 
 184:   if (i > text->size1 + text->gap + 1)
 185:     i -= text->gap;
 186:   else if (i > text->size1 + 1)
 187:     i = text->size1 + 1;
 188: 
 189:   if (i < 1 || i > text->size1 + text->size2 + 1)
 190:     abort ();
 191: 
 192:   return i;
 193: }
 194: 
 195: DEFUN ("copy-marker", Fcopy_marker, Scopy_marker, 1, 1, 0,
 196:   "Return a new marker pointing at the same place as MARKER.\n\
 197: If argument is a number, makes a new marker pointing\n\
 198: at that position in the current buffer.")
 199:   (marker)
 200:      Lisp_Object marker;
 201: {
 202:   Lisp_Object new;
 203: 
 204:   while (1)
 205:     {
 206:       if (XTYPE (marker) == Lisp_Int
 207:       || XTYPE (marker) == Lisp_Marker)
 208:     {
 209:       new = Fmake_marker ();
 210:       Fset_marker (new, marker,
 211:                XTYPE (marker) == Lisp_Marker
 212:                ? Fmarker_buffer (marker)
 213:                : Qnil);
 214:       return new;
 215:     }
 216:       else
 217:     marker = wrong_type_argument (Qinteger_or_marker_p, marker);
 218:     }
 219: }
 220: 
 221: syms_of_marker ()
 222: {
 223:   defsubr (&Smarker_position);
 224:   defsubr (&Smarker_buffer);
 225:   defsubr (&Sset_marker);
 226:   defalias (&Sset_marker, "move-marker");
 227:   defsubr (&Scopy_marker);
 228: }
Last modified: 1985-11-23
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 676
Valid CSS Valid XHTML 1.0 Strict