]> code.delx.au - gnu-emacs/blobdiff - src/indent.c
[TARGET_API_MAC_CARBON] (mac_do_receive_drag): Don't
[gnu-emacs] / src / indent.c
index cd4490445851438992621d0d0253241b0ecbbe07..89d83164560d5c2d73b38a8afb4fefce797cc493 100644 (file)
@@ -1,6 +1,6 @@
 /* Indentation functions.
    Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1998, 2000, 2001,
-                 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+                 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -335,8 +335,8 @@ DEFUN ("current-column", Fcurrent_column, Scurrent_column, 0, 0, 0,
        doc: /* Return the horizontal position of point.  Beginning of line is column 0.
 This is calculated by adding together the widths of all the displayed
 representations of the character between the start of the previous line
-and point.  (eg control characters will have a width of 2 or 4, tabs
-will have a variable width)
+and point (eg. control characters will have a width of 2 or 4, tabs
+will have a variable width).
 Ignores finite width of frame, which means that this function may return
 values greater than (frame-width).
 Whether the line is visible (if `selective-display' is t) has no effect;
@@ -734,8 +734,8 @@ string_display_width (string, beg, end)
 \f
 DEFUN ("indent-to", Findent_to, Sindent_to, 1, 2, "NIndent to column: ",
        doc: /* Indent from point with tabs and spaces until COLUMN is reached.
-Optional second argument MININUM says always do at least MININUM spaces
-even if that goes past COLUMN; by default, MININUM is zero.  */)
+Optional second argument MINIMUM says always do at least MINIMUM spaces
+even if that goes past COLUMN; by default, MINIMUM is zero.  */)
      (column, minimum)
      Lisp_Object column, minimum;
 {
@@ -2074,7 +2074,7 @@ whether or not it is currently displayed in some window.  */)
     {
       int it_start;
       int oselective;
-      int start_on_image_or_stretch_p;
+      int it_overshoot_expected;
 
       SET_TEXT_POS (pt, PT, PT_BYTE);
       start_display (&it, w, pt);
@@ -2086,8 +2086,31 @@ whether or not it is currently displayed in some window.  */)
         while the end position is really at some X > 0, the same X that
         PT had.  */
       it_start = IT_CHARPOS (it);
-      start_on_image_or_stretch_p = (it.method == GET_FROM_IMAGE
-                                    || it.method == GET_FROM_STRETCH);
+
+      /* We expect the call to move_it_to, further down, to overshoot
+        if the starting point is on an image, stretch glyph,
+        composition, or Lisp string.  We won't need to backtrack in
+        this situation, except for one corner case: when the Lisp
+        string contains a newline.  */
+      if (it.method == GET_FROM_STRING)
+       {
+         const char *s = SDATA (it.string);
+         const char *e = s + SBYTES (it.string);
+
+         while (s < e && *s != '\n')
+           ++s;
+
+         /* If there is no newline in the string, we need to check
+            whether there is a newline immediately after the string
+            in move_it_to below.  This may happen if there is an
+            overlay with an after-string just before the newline.  */
+         it_overshoot_expected = (s == e) ? -1 : 0;
+       }
+      else
+       it_overshoot_expected = (it.method == GET_FROM_IMAGE
+                                || it.method == GET_FROM_STRETCH
+                                || it.method == GET_FROM_COMPOSITION);
+
       reseat_at_previous_visible_line_start (&it);
       it.current_x = it.hpos = 0;
       /* Temporarily disable selective display so we don't move too far */
@@ -2098,16 +2121,19 @@ whether or not it is currently displayed in some window.  */)
 
       /* Move back if we got too far.  This may happen if
         truncate-lines is on and PT is beyond right margin.
-        It may also happen if it_start is on an image or a stretch
-        glyph -- in that case, don't go back.  */
+        Don't go back if the overshoot is expected (see above).  */
       if (IT_CHARPOS (it) > it_start && XINT (lines) > 0
-         && !start_on_image_or_stretch_p)
+         && (!it_overshoot_expected
+             || (it_overshoot_expected < 0
+                 && it.method == GET_FROM_BUFFER
+                 && it.c == '\n')))
        move_it_by_lines (&it, -1, 0);
 
       it.vpos = 0;
       /* Do this even if LINES is 0, so that we move back
         to the beginning of the current line as we ought.  */
-      move_it_by_lines (&it, XINT (lines), 0);
+      if (XINT (lines) >= 0 || IT_CHARPOS (it) > 0)
+       move_it_by_lines (&it, XINT (lines), 0);
 
       SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
     }