]> code.delx.au - gnu-emacs/blobdiff - src/indent.c
Merged from miles@gnu.org--gnu-2005 (patch 67, 270-278)
[gnu-emacs] / src / indent.c
index ffde428c12f823daba7feae8c22e9745765dc3fd..d6709d56ee891a41a7f7e775e3b0ee8592f4a5cc 100644 (file)
@@ -1,6 +1,6 @@
 /* Indentation functions.
-   Copyright (C) 1985,86,87,88,93,94,95,98,2000,01,02,03,2004
-   Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1998, 2000, 2001,
+     2002, 2003, 2004, 2005  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -67,6 +67,8 @@ static double position_indentation P_ ((int));
 
 int current_column_bol_cache;
 
+extern Lisp_Object Qfontification_functions;
+
 /* Get the display table to use for the current buffer.  */
 
 struct Lisp_Char_Table *
@@ -222,7 +224,7 @@ skip_invisible (pos, next_boundary_p, to, window)
      Lisp_Object window;
 {
   Lisp_Object prop, position, overlay_limit, proplimit;
-  Lisp_Object buffer;
+  Lisp_Object buffer, tmp;
   int end, inv_p;
 
   XSETFASTINT (position, pos);
@@ -253,8 +255,9 @@ skip_invisible (pos, next_boundary_p, to, window)
       /* No matter what. don't go past next overlay change.  */
       if (XFASTINT (overlay_limit) < XFASTINT (proplimit))
        proplimit = overlay_limit;
-      end = XFASTINT (Fnext_single_property_change (position, Qinvisible,
-                                                   buffer, proplimit));
+      tmp = Fnext_single_property_change (position, Qinvisible,
+                                         buffer, proplimit);
+      end = XFASTINT (tmp);
 #if 0
       /* Don't put the boundary in the middle of multibyte form if
          there is no actual property change.  */
@@ -341,7 +344,9 @@ 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;
-however, ^M is treated as end of line when `selective-display' is t.  */)
+however, ^M is treated as end of line when `selective-display' is t.
+Text that has an invisible property is considered as having width 0, unless
+`buffer-invisibility-spec' specifies that it is replaced by an ellipsis.  */)
      ()
 {
   Lisp_Object temp;
@@ -1885,7 +1890,7 @@ vmotion (from, vtarget, w)
   struct position pos;
   /* vpos is cumulative vertical position, changed as from is changed */
   register int vpos = 0;
-  Lisp_Object prevline;
+  int prevline;
   register int first;
   int from_byte;
   int lmargin = hscroll > 0 ? 1 - hscroll : 0;
@@ -1919,23 +1924,21 @@ vmotion (from, vtarget, w)
        {
          Lisp_Object propval;
 
-         XSETFASTINT (prevline, find_next_newline_no_quit (from - 1, -1));
-         while (XFASTINT (prevline) > BEGV
+         prevline = find_next_newline_no_quit (from - 1, -1);
+         while (prevline > BEGV
                 && ((selective > 0
-                     && indented_beyond_p (XFASTINT (prevline),
-                                           CHAR_TO_BYTE (XFASTINT (prevline)),
+                     && indented_beyond_p (prevline,
+                                           CHAR_TO_BYTE (prevline),
                                            (double) selective)) /* iftc */
-                    /* watch out for newlines with `invisible' property */
-                    || (propval = Fget_char_property (prevline,
+                    /* Watch out for newlines with `invisible' property.
+                       When moving upward, check the newline before.  */
+                    || (propval = Fget_char_property (make_number (prevline - 1),
                                                       Qinvisible,
                                                       text_prop_object),
                         TEXT_PROP_MEANS_INVISIBLE (propval))))
-           XSETFASTINT (prevline,
-                        find_next_newline_no_quit (XFASTINT (prevline) - 1,
-                                                   -1));
-         pos = *compute_motion (XFASTINT (prevline), 0,
-                                lmargin + (XFASTINT (prevline) == BEG
-                                           ? start_hpos : 0),
+           prevline = find_next_newline_no_quit (prevline - 1, -1);
+         pos = *compute_motion (prevline, 0,
+                                lmargin + (prevline == BEG ? start_hpos : 0),
                                 0,
                                 from,
                                 /* Don't care for VPOS...  */
@@ -1946,12 +1949,11 @@ vmotion (from, vtarget, w)
                                 /* This compensates for start_hpos
                                    so that a tab as first character
                                    still occupies 8 columns.  */
-                                (XFASTINT (prevline) == BEG
-                                 ? -start_hpos : 0),
+                                (prevline == BEG ? -start_hpos : 0),
                                 w);
          vpos -= pos.vpos;
          first = 0;
-         from = XFASTINT (prevline);
+         from = prevline;
        }
 
       /* If we made exactly the desired vertical distance,
@@ -1979,21 +1981,21 @@ vmotion (from, vtarget, w)
     {
       Lisp_Object propval;
 
-      XSETFASTINT (prevline, find_next_newline_no_quit (from, -1));
-      while (XFASTINT (prevline) > BEGV
+      prevline = find_next_newline_no_quit (from, -1);
+      while (prevline > BEGV
             && ((selective > 0
-                 && indented_beyond_p (XFASTINT (prevline),
-                                       CHAR_TO_BYTE (XFASTINT (prevline)),
+                 && indented_beyond_p (prevline,
+                                       CHAR_TO_BYTE (prevline),
                                        (double) selective)) /* iftc */
-                /* watch out for newlines with `invisible' property */
-                || (propval = Fget_char_property (prevline, Qinvisible,
+                /* Watch out for newlines with `invisible' property.
+                   When moving downward, check the newline after.  */
+                || (propval = Fget_char_property (make_number (prevline),
+                                                  Qinvisible,
                                                   text_prop_object),
                     TEXT_PROP_MEANS_INVISIBLE (propval))))
-       XSETFASTINT (prevline,
-                    find_next_newline_no_quit (XFASTINT (prevline) - 1,
-                                               -1));
-      pos = *compute_motion (XFASTINT (prevline), 0,
-                            lmargin + (XFASTINT (prevline) == BEG
+       prevline = find_next_newline_no_quit (prevline - 1, -1);
+      pos = *compute_motion (prevline, 0,
+                            lmargin + (prevline == BEG
                                        ? start_hpos : 0),
                             0,
                             from,
@@ -2002,7 +2004,7 @@ vmotion (from, vtarget, w)
                             /* ... nor HPOS.  */
                             1 << (BITS_PER_SHORT - 1),
                             -1, hscroll,
-                            (XFASTINT (prevline) == BEG ? -start_hpos : 0),
+                            (prevline == BEG ? -start_hpos : 0),
                             w);
       did_motion = 1;
     }
@@ -2049,6 +2051,7 @@ whether or not it is currently displayed in some window.  */)
   struct window *w;
   Lisp_Object old_buffer;
   struct gcpro gcpro1;
+  int count = SPECPDL_INDEX ();
 
   CHECK_NUMBER (lines);
   if (! NILP (window))
@@ -2066,25 +2069,55 @@ whether or not it is currently displayed in some window.  */)
       XSETBUFFER (w->buffer, current_buffer);
     }
 
-  SET_TEXT_POS (pt, PT, PT_BYTE);
-  start_display (&it, w, pt);
-
-  /* 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);
+  /* Don't fontify text that we just move across.  */
+  specbind (Qfontification_functions, Qnil);
 
-  if (XINT (lines) != 0)
-    move_it_by_lines (&it, XINT (lines), 0);
-
-  SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
+  if (noninteractive)
+    {
+      struct position pos;
+      pos = *vmotion (PT, XINT (lines), w);
+      SET_PT_BOTH (pos.bufpos, pos.bytepos);
+    }
+  else
+    {
+      int it_start;
+      int oselective;
+
+      SET_TEXT_POS (pt, PT, PT_BYTE);
+      start_display (&it, w, pt);
+
+      /* Scan from the start of the 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.  */
+      it_start = IT_CHARPOS (it);
+      reseat_at_previous_visible_line_start (&it);
+      it.current_x = it.hpos = 0;
+      /* Temporarily disable selective display so we don't move too far */
+      oselective = it.selective;
+      it.selective = 0;
+      move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
+      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)
+       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);
+
+      SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
+    }
 
   if (BUFFERP (old_buffer))
     w->buffer = old_buffer;
 
+  unbind_to (count, Qnil);
   RETURN_UNGCPRO (make_number (it.vpos));
 }