]> code.delx.au - gnu-emacs/blobdiff - src/indent.c
(selection-coding-system): Fix docstring.
[gnu-emacs] / src / indent.c
index a810dd3189ba65e58e143539fea5c7d579a4d965..3cbb105e80fdcf260b65e37d9219d4b6ec2a039d 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 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -16,8 +16,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 #include <config.h>
 #include "lisp.h"
@@ -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,6 +2074,7 @@ whether or not it is currently displayed in some window.  */)
     {
       int it_start;
       int oselective;
+      int it_overshoot_expected_p;
 
       SET_TEXT_POS (pt, PT, PT_BYTE);
       start_display (&it, w, pt);
@@ -2085,6 +2086,26 @@ 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);
+
+      /* We expect the call to move_it_to, further down, to overshoot
+        if the starting point is on an image, stretch glyph, 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;
+
+         it_overshoot_expected_p = (s == e);
+       }
+      else
+       it_overshoot_expected_p = (it.method == GET_FROM_IMAGE
+                                  || it.method == GET_FROM_STRETCH);
+
       reseat_at_previous_visible_line_start (&it);
       it.current_x = it.hpos = 0;
       /* Temporarily disable selective display so we don't move too far */
@@ -2094,14 +2115,17 @@ whether or not it is currently displayed in some window.  */)
       it.selective = oselective;
 
       /* Move back if we got too far.  This may happen if
-        truncate-lines is on and PT is beyond right margin.  */
-      if (IT_CHARPOS (it) > it_start && XINT (lines) > 0)
+        truncate-lines is on and PT is beyond right margin.
+        Don't go back if the overshoot is expected (see above).  */
+      if (IT_CHARPOS (it) > it_start && XINT (lines) > 0
+         && !it_overshoot_expected_p)
        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));
     }