(enum fringe_bitmap_type): Define here.
[bpt/emacs.git] / src / indent.c
index 2a62ab6..22039eb 100644 (file)
@@ -1,5 +1,5 @@
 /* Indentation functions.
-   Copyright (C) 1985,86,87,88,93,94,95,98, 2000, 2001
+   Copyright (C) 1985,86,87,88,93,94,95,98, 2000, 2001, 2002
    Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -47,7 +47,7 @@ int indent_tabs_mode;
    Some things in set last_known_column_point to -1
    to mark the memorized value as invalid.  */
 
-int last_known_column;
+double last_known_column;
 
 /* Value of point when current_column was called.  */
 
@@ -57,8 +57,8 @@ int last_known_column_point;
 
 int last_known_column_modified;
 
-static int current_column_1 P_ ((void));
-static int position_indentation P_ ((int));
+static double current_column_1 P_ ((void));
+static double position_indentation P_ ((int));
 
 /* Cache of beginning of line found by the last call of
    current_column. */
@@ -221,7 +221,7 @@ skip_invisible (pos, next_boundary_p, to, window)
 {
   Lisp_Object prop, position, overlay_limit, proplimit;
   Lisp_Object buffer;
-  int end;
+  int end, inv_p;
 
   XSETFASTINT (position, pos);
   XSETBUFFER (buffer, current_buffer);
@@ -266,11 +266,13 @@ skip_invisible (pos, next_boundary_p, to, window)
     }
   /* if the `invisible' property is set, we can skip to
      the next property change */
-  if (!NILP (window) && EQ (XWINDOW (window)->buffer, buffer))
-    prop = Fget_char_property (position, Qinvisible, window);
-  else
-    prop = Fget_char_property (position, Qinvisible, buffer);
-  if (TEXT_PROP_MEANS_INVISIBLE (prop) > NILP (window))
+  prop = Fget_char_property (position, Qinvisible,
+                            (!NILP (window)
+                             && EQ (XWINDOW (window)->buffer, buffer))
+                            ? window : buffer);
+  inv_p = TEXT_PROP_MEANS_INVISIBLE (prop);
+  /* When counting columns (window == nil), don't skip over ellipsis text.  */
+  if (NILP (window) ? inv_p == 1 : inv_p)
     return *next_boundary_p;
   return pos;
 }
@@ -327,6 +329,7 @@ check_composition (pos, pos_byte, point, len, len_byte, width)
       }                                                                        \
   } while (0)
 
+
 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
@@ -340,7 +343,7 @@ however, ^M is treated as end of line when `selective-display' is t.  */)
      ()
 {
   Lisp_Object temp;
-  XSETFASTINT (temp, current_column ());
+  XSETFASTINT (temp, (int) current_column ()); /* iftc */
   return temp;
 }
 
@@ -352,7 +355,7 @@ invalidate_current_column ()
   last_known_column_point = 0;
 }
 
-int
+double
 current_column ()
 {
   register int col;
@@ -399,25 +402,25 @@ current_column ()
     {
       EMACS_INT i, n;
       Lisp_Object charvec;
-       
+
       if (ptr == stop)
        {
          /* We stopped either for the beginning of the buffer
             or for the gap.  */
          if (ptr == BEGV_ADDR)
            break;
-         
+
          /* It was the gap.  Jump back over it.  */
          stop = BEGV_ADDR;
          ptr = GPT_ADDR;
-         
+
          /* Check whether that brings us to beginning of buffer.  */
          if (BEGV >= GPT)
            break;
        }
 
       c = *--ptr;
-      
+
       if (dp && VECTORP (DISP_CHAR_VECTOR (dp, c)))
        {
          charvec = DISP_CHAR_VECTOR (dp, c);
@@ -428,7 +431,7 @@ current_column ()
          charvec = Qnil;
          n = 1;
        }
-           
+
       for (i = n - 1; i >= 0; --i)
        {
          if (VECTORP (charvec))
@@ -436,14 +439,14 @@ current_column ()
              /* This should be handled the same as
                 next_element_from_display_vector does it.  */
              Lisp_Object entry = AREF (charvec, i);
-             
+
              if (INTEGERP (entry)
                  && GLYPH_CHAR_VALID_P (XFASTINT (entry)))
                c = FAST_GLYPH_CHAR (XFASTINT (entry));
              else
                c = ' ';
            }
-      
+
          if (c >= 040 && c < 0177)
            col++;
          else if (c == '\n'
@@ -457,7 +460,7 @@ current_column ()
            {
              if (tab_seen)
                col = ((col + tab_width) / tab_width) * tab_width;
-             
+
              post_tab += col;
              col = 0;
              tab_seen = 1;
@@ -499,7 +502,7 @@ current_column ()
    This function handles characters that are invisible
    due to text properties or overlays.  */
 
-static int
+static double
 current_column_1 ()
 {
   register int tab_width = XINT (current_buffer->tab_width);
@@ -510,7 +513,7 @@ current_column_1 ()
   /* Start the scan at the beginning of this line with column number 0.  */
   register int col = 0;
   int scan, scan_byte;
-  int next_boundary, next_boundary_byte;
+  int next_boundary;
   int opoint = PT, opoint_byte = PT_BYTE;
 
   scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
@@ -518,7 +521,6 @@ current_column_1 ()
   scan = PT, scan_byte = PT_BYTE;
   SET_PT_BOTH (opoint, opoint_byte);
   next_boundary = scan;
-  next_boundary_byte = scan_byte;
 
   if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
 
@@ -538,7 +540,6 @@ current_column_1 ()
            goto endloop;
          if (scan != old_scan)
            scan_byte = CHAR_TO_BYTE (scan);
-         next_boundary_byte = CHAR_TO_BYTE (next_boundary);
        }
 
       /* Check composition sequence.  */
@@ -590,7 +591,6 @@ current_column_1 ()
                goto endloop;
              if (c == '\t')
                {
-                 int prev_col = col;
                  col += tab_width;
                  col = col / tab_width * tab_width;
                }
@@ -609,7 +609,6 @@ current_column_1 ()
            goto endloop;
          if (c == '\t')
            {
-             int prev_col = col;
              col += tab_width;
              col = col / tab_width * tab_width;
            }
@@ -617,11 +616,13 @@ current_column_1 ()
            {
              unsigned char *ptr;
              int bytes, width, wide_column;
-             
-             scan_byte--;
+
              ptr = BYTE_POS_ADDR (scan_byte);
              MULTIBYTE_BYTES_WIDTH (ptr, dp);
              scan_byte += bytes;
+             /* Subtract one to compensate for the increment
+                that is going to happen below.  */
+             scan_byte--;
              col += width;
            }
          else if (ctl_arrow && (c < 040 || c == 0177))
@@ -651,7 +652,7 @@ current_column_1 ()
    If BEG is nil, that stands for the beginning of STRING.
    If END is nil, that stands for the end of STRING.  */
 
-static int
+static double
 string_display_width (string, beg, end)
      Lisp_Object string, beg, end;
 {
@@ -666,7 +667,7 @@ string_display_width (string, beg, end)
   int b, e;
 
   if (NILP (end))
-    e = XSTRING (string)->size;
+    e = SCHARS (string);
   else
     {
       CHECK_NUMBER (end);
@@ -682,10 +683,10 @@ string_display_width (string, beg, end)
     }
 
   /* Make a pointer for decrementing through the chars before point.  */
-  ptr = XSTRING (string)->data + e;
+  ptr = SDATA (string) + e;
   /* Make a pointer to where consecutive chars leave off,
      going backwards from point.  */
-  stop = XSTRING (string)->data + b;
+  stop = SDATA (string) + b;
 
   if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
 
@@ -777,7 +778,7 @@ even if that goes past COLUMN; by default, MININUM is zero.  */)
 }
 
 \f
-static int position_indentation P_ ((int));
+static double position_indentation P_ ((int));
 
 DEFUN ("current-indentation", Fcurrent_indentation, Scurrent_indentation,
        0, 0, 0,
@@ -791,12 +792,12 @@ following any initial whitespace.  */)
 
   scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
 
-  XSETFASTINT (val, position_indentation (PT_BYTE));
+  XSETFASTINT (val, (int) position_indentation (PT_BYTE)); /* iftc */
   SET_PT_BOTH (opoint, opoint_byte);
   return val;
 }
 
-static int
+static double
 position_indentation (pos_byte)
      register int pos_byte;
 {
@@ -846,7 +847,7 @@ position_indentation (pos_byte)
          /* The -1 and +1 arrange to point at the first byte of gap
             (if STOP_POS_BYTE is the position of the gap)
             rather than at the data after the gap.  */
-            
+
          stop = BYTE_POS_ADDR (stop_pos_byte - 1) + 1;
          p = BYTE_POS_ADDR (pos_byte);
        }
@@ -888,9 +889,10 @@ position_indentation (pos_byte)
 
 int
 indented_beyond_p (pos, pos_byte, column)
-     int pos, pos_byte, column;
+     int pos, pos_byte;
+     double column;
 {
-  int val;
+  double val;
   int opoint = PT, opoint_byte = PT_BYTE;
 
   SET_PT_BOTH (pos, pos_byte);
@@ -899,7 +901,7 @@ indented_beyond_p (pos, pos_byte, column)
 
   val = position_indentation (PT_BYTE);
   SET_PT_BOTH (opoint, opoint_byte);
-  return val >= column;
+  return val >= column;                 /* hmm, float comparison */
 }
 \f
 DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2, "p",
@@ -934,9 +936,7 @@ The return value is the current column.  */)
   Lisp_Object val;
   int prev_col = 0;
   int c = 0;
-  int next_boundary;
-
-  int pos_byte, end_byte, next_boundary_byte;
+  int next_boundary, pos_byte;
 
   if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
   CHECK_NATNUM (column);
@@ -945,9 +945,7 @@ The return value is the current column.  */)
   pos = PT;
   pos_byte = PT_BYTE;
   end = ZV;
-  end_byte = ZV_BYTE;
   next_boundary = pos;
-  next_boundary_byte = PT_BYTE;
 
   /* If we're starting past the desired column,
      back up to beginning of line and scan from there.  */
@@ -967,7 +965,6 @@ The return value is the current column.  */)
          pos = skip_invisible (pos, &next_boundary, end, Qnil);
          if (pos != prev)
            pos_byte = CHAR_TO_BYTE (pos);
-         next_boundary_byte = CHAR_TO_BYTE (next_boundary);
          if (pos >= end)
            goto endloop;
        }
@@ -1098,7 +1095,7 @@ The return value is the current column.  */)
       goal_pt_byte = PT_BYTE;
       Findent_to (make_number (col), Qnil);
       SET_PT_BOTH (goal_pt, goal_pt_byte);
-      
+
       /* Set the last_known... vars consistently.  */
       col = goal;
     }
@@ -1262,7 +1259,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
          int newpos;
 
          /* Don't skip invisible if we are already at the margin.  */
-         if (vpos > tovpos || vpos == tovpos && hpos >= tohpos)
+         if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos))
            {
              if (contin_hpos && prev_hpos == 0
                  && hpos > tohpos
@@ -1357,7 +1354,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
             W_      ^---- next after the point
             ^----  next char. after the point.
             ----------
-                     In case of wide-column character 
+                     In case of wide-column character
 
         The problem here is continuation at a wide-column character.
         In this case, the line may shorter less than WIDTH.
@@ -1444,7 +1441,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
          break;
        }
 
-      if (vpos > tovpos || vpos == tovpos && hpos >= tohpos)
+      if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos))
        {
          if (contin_hpos && prev_hpos == 0
              && hpos > tohpos
@@ -1527,7 +1524,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
        {
          EMACS_INT i, n;
          Lisp_Object charvec;
-         
+
          c = FETCH_BYTE (pos_byte);
 
          /* Check composition sequence.  */
@@ -1593,14 +1590,14 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
                  /* This should be handled the same as
                     next_element_from_display_vector does it.  */
                  Lisp_Object entry = AREF (charvec, i);
-             
+
                  if (INTEGERP (entry)
                      && GLYPH_CHAR_VALID_P (XFASTINT (entry)))
                    c = FAST_GLYPH_CHAR (XFASTINT (entry));
                  else
                    c = ' ';
                }
-      
+
              if (c >= 040 && c < 0177)
                hpos++;
              else if (c == '\t')
@@ -1614,7 +1611,8 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
              else if (c == '\n')
                {
                  if (selective > 0
-                     && indented_beyond_p (pos, pos_byte, selective))
+                     && indented_beyond_p (pos, pos_byte,
+                                            (double) selective)) /* iftc */
                    {
                      /* If (pos == to), we don't have to take care of
                         selective display.  */
@@ -1629,7 +1627,8 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
                              pos_byte = CHAR_TO_BYTE (pos);
                            }
                          while (pos < to
-                                && indented_beyond_p (pos, pos_byte, selective));
+                                && indented_beyond_p (pos, pos_byte,
+                                                       (double) selective)); /* iftc */
                          /* Allow for the " ..." that is displayed for them. */
                          if (selective_rlen)
                            {
@@ -1879,7 +1878,7 @@ vmotion (from, vtarget, w)
                 && ((selective > 0
                      && indented_beyond_p (XFASTINT (prevline),
                                            CHAR_TO_BYTE (XFASTINT (prevline)),
-                                           selective))
+                                           (double) selective)) /* iftc */
                     /* watch out for newlines with `invisible' property */
                     || (propval = Fget_char_property (prevline,
                                                       Qinvisible,
@@ -1892,7 +1891,7 @@ vmotion (from, vtarget, w)
                                 lmargin + (XFASTINT (prevline) == BEG
                                            ? start_hpos : 0),
                                 0,
-                                from, 
+                                from,
                                 /* Don't care for VPOS...  */
                                 1 << (BITS_PER_SHORT - 1),
                                 /* ... nor HPOS.  */
@@ -1939,7 +1938,7 @@ vmotion (from, vtarget, w)
             && ((selective > 0
                  && indented_beyond_p (XFASTINT (prevline),
                                        CHAR_TO_BYTE (XFASTINT (prevline)),
-                                       selective))
+                                       (double) selective)) /* iftc */
                 /* watch out for newlines with `invisible' property */
                 || (propval = Fget_char_property (prevline, Qinvisible,
                                                   text_prop_object),
@@ -1951,7 +1950,7 @@ vmotion (from, vtarget, w)
                             lmargin + (XFASTINT (prevline) == BEG
                                        ? start_hpos : 0),
                             0,
-                            from, 
+                            from,
                             /* Don't care for VPOS...  */
                             1 << (BITS_PER_SHORT - 1),
                             /* ... nor HPOS.  */
@@ -2020,15 +2019,26 @@ whether or not it is currently displayed in some window.  */)
       old_buffer = w->buffer;
       XSETBUFFER (w->buffer, current_buffer);
     }
-      
+
   SET_TEXT_POS (pt, PT, PT_BYTE);
   start_display (&it, w, pt);
-  move_it_by_lines (&it, XINT (lines), 0);
+
+  /* Move to the start of the display line containing PT.  If we don't
+     do this, we start moving with IT->current_x == 0, while PT is
+     really at some x > 0.  The effect is, in continuation lines, that
+     we end up with the iterator placed at where it thinks X is 0,
+     while the end position is really at some X > 0, the same X that
+     PT had.  */
+  move_it_by_lines (&it, 0, 0);
+
+  if (XINT (lines) != 0)
+    move_it_by_lines (&it, XINT (lines), 0);
+
   SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
 
   if (BUFFERP (old_buffer))
     w->buffer = old_buffer;
-  
+
   RETURN_UNGCPRO (make_number (it.vpos));
 }