diff src/editfns.c @ 26389:e2acf63b5403

(Fline_beginning_position): If N is not 1, pass t to Fconstrain_to_field for ESCAPE-FROM-EDGE. (preceding_pos): Function deleted. (text_property_stickiness): Decrement POS directly. Fix a confusion that used PT instead of POS. (find_field): Properly handle the case of a field boundary where `field' inherits from neither side. (Ffield_beginning, Ffield_end): Doc fixes. (Ferase_field, Ffield_string, Ffield_string_no_properties): Doc fixes.
author Richard M. Stallman <rms@gnu.org>
date Tue, 09 Nov 1999 18:42:28 +0000
parents f35140f031b4
children bda6a3a2bf96
line wrap: on
line diff
--- a/src/editfns.c	Tue Nov 09 15:49:34 1999 +0000
+++ b/src/editfns.c	Tue Nov 09 18:42:28 1999 +0000
@@ -272,23 +272,9 @@
   return current_buffer->mark;
 }
 
-/* Returns the position before POS in the current buffer.  POS must not
-   be at the beginning of the buffer.  */
-static Lisp_Object
-preceding_pos (int pos)
-{
-  int pos_byte = CHAR_TO_BYTE (pos);
-	  
-  /* Decrement POS_BYTE (is all this cruft really necessary?).  */
-  if (NILP (current_buffer->enable_multibyte_characters))
-    pos_byte--;
-  else
-    DEC_POS (pos_byte);
-
-  return make_number (BYTE_TO_CHAR (pos_byte));
-}
-
-/* Returns true if POS1 and POS2 have the same value for text property PROP. */
+/* Return nonzero if POS1 and POS2 have the same value
+   for the text property PROP.  */
+
 static int
 text_property_eq (prop, pos1, pos2)
      Lisp_Object prop;
@@ -302,9 +288,11 @@
   return EQ (pval1, pval2);
 }
 
-/* Returns the direction that the text-property PROP would be inherited
-   by any new text inserted at POS: 1 if it would be inherited from POS,
-   -1 if it would be inherited from POS-1, and 0 if from neither.  */
+/* Return the direction from which the text-property PROP would be
+   inherited by any new text inserted at POS: 1 if it would be
+   inherited from the char after POS, -1 if it would be inherited from
+   the char before POS, and 0 if from neither.  */
+
 static int
 text_property_stickiness (prop, pos)
      Lisp_Object prop;
@@ -312,58 +300,60 @@
 {
   Lisp_Object front_sticky;
 
-  if (PT > BEGV)
-    /* Consider previous position.  */
+  if (XINT (pos) > BEGV)
+    /* Consider previous character.  */
     {
       Lisp_Object prev_pos, rear_non_sticky;
 
-      prev_pos = preceding_pos (pos);
+      prev_pos = make_number (XINT (pos) - 1);
       rear_non_sticky = Fget_text_property (prev_pos, Qrear_nonsticky, Qnil);
 
       if (EQ (rear_non_sticky, Qnil)
 	  || (CONSP (rear_non_sticky)
 	      && !Fmemq (prop, rear_non_sticky)))
 	/* PROP is not rear-non-sticky, and since this takes precedence over
-	   any front-stickiness, that must be the answer.  */
+	   any front-stickiness, PROP is inherited from before.  */
 	return -1;
     }
 
-  /* Consider current position.  */
+  /* Consider following character.  */
   front_sticky = Fget_text_property (pos, Qfront_sticky, Qnil);
 
   if (EQ (front_sticky, Qt)
       || (CONSP (front_sticky)
 	  && Fmemq (prop, front_sticky)))
-    /* PROP is front-sticky.  */
+    /* PROP is inherited from after.  */
     return 1;
 
-  /* PROP is not sticky at all.  */
+  /* PROP is not inherited from either side.  */
   return 0;
 }
 
-/* Name for the text property we use to distinguish fields. */
+/* Symbol for the text property used to mark fields.  */
 Lisp_Object Qfield;
 
-/* Returns the field surrounding POS in *BEG and *END; an
-   `field' is a region of text with the same `field' property.
-   If POS is nil, the position of the current buffer's point is used.
-   If MERGE_AT_BOUNDARY is true, then if POS is at the very first
+/* Find the field surrounding POS in *BEG and *END.  If POS is nil,
+   the value of point is used instead.
+
+   If MERGE_AT_BOUNDARY is nonzero, then if POS is at the very first
    position of a field, then the beginning of the previous field
    is returned instead of the beginning of POS's field (since the end of
    a field is actually also the beginning of the next input
-   field, this behavior is sometimes useful).  BEG or END may be 0, in
-   which case the corresponding value is not returned.  */
+   field, this behavior is sometimes useful).
+
+   Either BEG or END may be 0, in which case the corresponding value
+   is not stored.  */
+
 void
 find_field (pos, merge_at_boundary, beg, end)
      Lisp_Object pos;
      Lisp_Object merge_at_boundary;
      int *beg, *end;
 {
-  /* If POS is at the edge of a field, then -1 or 1 depending on
-     whether it should be considered as the beginning of the following
-     field, or the end of the previous field, respectively.  If POS is
-     not at a field-boundary, then STICKINESS is 0.  */
-  int stickiness = 0;
+  /* 1 if POS counts as the start of a field.  */
+  int at_field_start = 0;
+  /* 1 if POS counts as the end of a field.  */
+  int at_field_end = 0;
   
   if (NILP (pos))
     XSETFASTINT (pos, PT);
@@ -382,30 +372,35 @@
       Lisp_Object after_field, before_field;
 
       after_field = Fget_text_property (pos, Qfield, Qnil);
-      before_field = Fget_text_property (preceding_pos (pos), Qfield, Qnil);
+      before_field = Fget_text_property (make_number (XINT (pos) - 1),
+					 Qfield, Qnil);
 
       if (! EQ (after_field, before_field))
 	/* We are at a boundary, see which direction is inclusive.  */
 	{
-	  stickiness = text_property_stickiness (Qfield, pos);
-
-	  if (stickiness == 0)
+	  int stickiness = text_property_stickiness (Qfield, pos);
+
+	  if (stickiness > 0)
+	    at_field_start = 1;
+	  else if (stickiness < 0)
+	    at_field_end = 1;
+	  else
 	    /* STICKINESS == 0 means that any inserted text will get a
 	       `field' text-property of nil, so check to see if that
 	       matches either of the adjacent characters (this being a
-	       kind of `stickiness by default').  */
+	       kind of "stickiness by default").  */
 	    {
 	      if (NILP (before_field))
-		stickiness = -1; /* Sticks to the left.  */
+		at_field_end = 1; /* Sticks to the left.  */
 	      else if (NILP (after_field))
-		stickiness = 1;	/* Sticks to the right.  */
+		at_field_start = 1; /* Sticks to the right.  */
 	    }
 	}
     }
 
   if (beg)
     {
-      if (stickiness > 0)
+      if (at_field_start)
 	/* POS is at the edge of a field, and we should consider it as
 	   the beginning of the following field.  */
 	*beg = XFASTINT (pos);
@@ -414,13 +409,13 @@
 	{
 	  Lisp_Object prev;
 	  prev = Fprevious_single_property_change (pos, Qfield, Qnil, Qnil);
-	  *beg = NILP(prev) ? BEGV : XFASTINT (prev);
+	  *beg = NILP (prev) ? BEGV : XFASTINT (prev);
 	}
     }
 
   if (end)
     {
-      if (stickiness < 0)
+      if (at_field_end)
 	/* POS is at the edge of a field, and we should consider it as
 	   the end of the previous field.  */
 	*end = XFASTINT (pos);
@@ -429,7 +424,7 @@
 	{
 	  Lisp_Object next;
 	  next = Fnext_single_property_change (pos, Qfield, Qnil, Qnil);
-	  *end = NILP(next) ? ZV : XFASTINT (next);
+	  *end = NILP (next) ? ZV : XFASTINT (next);
 	}
     }
 }
@@ -437,7 +432,7 @@
 DEFUN ("delete-field", Fdelete_field, Sdelete_field, 0, 1, "d",
   "Delete the field surrounding POS.\n\
 A field is a region of text with the same `field' property.\n\
-If POS is nil, the position of the current buffer's point is used.")
+If POS is nil, the value of point is used for POS.")
   (pos)
      Lisp_Object pos;
 {
@@ -450,7 +445,7 @@
 DEFUN ("field-string", Ffield_string, Sfield_string, 0, 1, 0,
   "Return the contents of the field surrounding POS as a string.\n\
 A field is a region of text with the same `field' property.\n\
-If POS is nil, the position of the current buffer's point is used.")
+If POS is nil, the value of point is used for POS.")
   (pos)
      Lisp_Object pos;
 {
@@ -462,7 +457,7 @@
 DEFUN ("field-string-no-properties", Ffield_string_no_properties, Sfield_string_no_properties, 0, 1, 0,
   "Return the contents of the field around POS, without text-properties.\n\
 A field is a region of text with the same `field' property.\n\
-If POS is nil, the position of the current buffer's point is used.")
+If POS is nil, the value of point is used for POS.")
   (pos)
      Lisp_Object pos;
 {
@@ -474,8 +469,8 @@
 DEFUN ("field-beginning", Ffield_beginning, Sfield_beginning, 0, 2, 0,
   "Return the beginning of the field surrounding POS.\n\
 A field is a region of text with the same `field' property.\n\
-If POS is nil, the position of the current buffer's point is used.\n\
-If ESCAPE-FROM-EDGE is non-nil and POS is already at beginning of an\n\
+If POS is nil, the value of point is used for POS.\n\
+If ESCAPE-FROM-EDGE is non-nil and POS is at the beginning of its\n\
 field, then the beginning of the *previous* field is returned.")
   (pos, escape_from_edge)
      Lisp_Object pos, escape_from_edge;
@@ -488,8 +483,8 @@
 DEFUN ("field-end", Ffield_end, Sfield_end, 0, 2, 0,
   "Return the end of the field surrounding POS.\n\
 A field is a region of text with the same `field' property.\n\
-If POS is nil, the position of the current buffer's point is used.\n\
-If ESCAPE-FROM-EDGE is non-nil and POS is already at end of a field,\n\
+If POS is nil, the value of point is used for POS.\n\
+If ESCAPE-FROM-EDGE is non-nil and POS is at the end of its field,\n\
 then the end of the *following* field is returned.")
   (pos, escape_from_edge)
      Lisp_Object pos, escape_from_edge;
@@ -578,10 +573,10 @@
   "Return the character position of the first character on the current line.\n\
 With argument N not nil or 1, move forward N - 1 lines first.\n\
 If scan reaches end of buffer, return that position.\n\
-This function does not move point.\n\n\
-In the minibuffer, if point is not within the prompt,\n\
-the return value is never within the prompt either.")
-
+The scan does not cross a field boundary unless it would move\n\
+beyond there to a different line.  And if N is nil or 1,\n\
+and scan starts at a field boundary, the scan stops as soon as it starts.\n\n\
+This function does not move point.")
   (n)
      Lisp_Object n;
 {
@@ -600,7 +595,9 @@
   SET_PT_BOTH (orig, orig_byte);
 
   /* Return END constrained to the current input field.  */
-  return Fconstrain_to_field (make_number (end), make_number (orig), Qnil, Qt);
+  return Fconstrain_to_field (make_number (end), make_number (orig),
+			      XINT (n) != 1 ? Qt : Qnil,
+			      Qt);
 }
 
 DEFUN ("line-end-position", Fline_end_position, Sline_end_position,