Merge from emacs-24; up to 2012-12-23T02:41:17Z!rgm@gnu.org
[bpt/emacs.git] / src / indent.c
index 3332228..9bf75bc 100644 (file)
@@ -1,6 +1,6 @@
 /* Indentation functions.
-   Copyright (C) 1985-1988, 1993-1995, 1998, 2000-2012
-                 Free Software Foundation, Inc.
+   Copyright (C) 1985-1988, 1993-1995, 1998, 2000-2013 Free Software
+   Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -138,7 +138,7 @@ recompute_width_table (struct buffer *buf, struct Lisp_Char_Table *disptab)
   struct Lisp_Vector *widthtab;
 
   if (!VECTORP (BVAR (buf, width_table)))
-    bset_width_table (buf, Fmake_vector (make_number (256), make_number (0)));
+    bset_width_table (buf, make_uninit_vector (256));
   widthtab = XVECTOR (BVAR (buf, width_table));
   eassert (widthtab->header.size == 256);
 
@@ -291,7 +291,7 @@ 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
+and point (e.g., 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).
@@ -571,7 +571,8 @@ scan_for_column (ptrdiff_t *endpos, EMACS_INT *goalcol, ptrdiff_t *prevcol)
            col += width;
            if (endp > scan) /* Avoid infinite loops with 0-width overlays.  */
              {
-               scan = endp; scan_byte = charpos_to_bytepos (scan);
+               scan = endp;
+               scan_byte = CHAR_TO_BYTE (scan);
                continue;
              }
          }
@@ -1327,8 +1328,7 @@ compute_motion (ptrdiff_t from, EMACS_INT fromvpos, EMACS_INT fromhpos,
                  TO (we need to go back below).  */
              if (pos <= to)
                {
-                 pos = find_before_next_newline (pos, to, 1);
-                 pos_byte = CHAR_TO_BYTE (pos);
+                 pos = find_before_next_newline (pos, to, 1, &pos_byte);
                  hpos = width;
                  /* If we just skipped next_boundary,
                     loop around in the main while
@@ -1582,10 +1582,9 @@ compute_motion (ptrdiff_t from, EMACS_INT fromvpos, EMACS_INT fromhpos,
                          /* Skip any number of invisible lines all at once */
                          do
                            {
-                             pos = find_before_next_newline (pos, to, 1);
+                             pos = find_before_next_newline (pos, to, 1, &pos_byte);
                              if (pos < to)
-                               pos++;
-                             pos_byte = CHAR_TO_BYTE (pos);
+                               INC_BOTH (pos, pos_byte);
                            }
                          while (pos < to
                                 && indented_beyond_p (pos, pos_byte,
@@ -1621,10 +1620,7 @@ compute_motion (ptrdiff_t from, EMACS_INT fromvpos, EMACS_INT fromhpos,
                     everything from a ^M to the end of the line is invisible.
                     Stop *before* the real newline.  */
                  if (pos < to)
-                   {
-                     pos = find_before_next_newline (pos, to, 1);
-                     pos_byte = CHAR_TO_BYTE (pos);
-                   }
+                   pos = find_before_next_newline (pos, to, 1, &pos_byte);
                  /* If we just skipped next_boundary,
                     loop around in the main while
                     and handle it.  */
@@ -1764,11 +1760,7 @@ visible section of the buffer, and pass LINE and COL as TOPOS.  */)
   else
     hscroll = tab_offset = 0;
 
-  if (NILP (window))
-    window = Fselected_window ();
-  else
-    CHECK_LIVE_WINDOW (window);
-  w = XWINDOW (window);
+  w = decode_live_window (window);
 
   if (XINT (from) < BEGV || XINT (from) > ZV)
     args_out_of_range_3 (from, make_number (BEGV), make_number (ZV));
@@ -1790,8 +1782,7 @@ visible section of the buffer, and pass LINE and COL as TOPOS.  */)
                               1))
                         : XINT (XCAR (topos))),
                        (NILP (width) ? -1 : XINT (width)),
-                       hscroll, tab_offset,
-                       XWINDOW (window));
+                       hscroll, tab_offset, w);
 
   XSETFASTINT (bufpos, pos->bufpos);
   XSETINT (hpos, pos->hpos);
@@ -1849,21 +1840,20 @@ vmotion (register ptrdiff_t from, register EMACS_INT vtarget, struct window *w)
 
       while ((vpos > vtarget || first) && from > BEGV)
        {
+         ptrdiff_t bytepos;
          Lisp_Object propval;
 
-         prevline = find_next_newline_no_quit (from - 1, -1);
+         prevline = find_next_newline_no_quit (from - 1, -1, &bytepos);
          while (prevline > BEGV
                 && ((selective > 0
-                     && indented_beyond_p (prevline,
-                                           CHAR_TO_BYTE (prevline),
-                                           selective))
+                     && indented_beyond_p (prevline, bytepos, selective))
                     /* 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))))
-           prevline = find_next_newline_no_quit (prevline - 1, -1);
+           prevline = find_next_newline_no_quit (prevline - 1, -1, &bytepos);
          pos = *compute_motion (prevline, 0,
                                 lmargin,
                                 0,
@@ -1901,21 +1891,20 @@ vmotion (register ptrdiff_t from, register EMACS_INT vtarget, struct window *w)
   from_byte = CHAR_TO_BYTE (from);
   if (from > BEGV && FETCH_BYTE (from_byte - 1) != '\n')
     {
+      ptrdiff_t bytepos;
       Lisp_Object propval;
 
-      prevline = find_next_newline_no_quit (from, -1);
+      prevline = find_next_newline_no_quit (from, -1, &bytepos);
       while (prevline > BEGV
             && ((selective > 0
-                 && indented_beyond_p (prevline,
-                                       CHAR_TO_BYTE (prevline),
-                                       selective))
+                 && indented_beyond_p (prevline, bytepos, selective))
                 /* 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))))
-       prevline = find_next_newline_no_quit (prevline - 1, -1);
+       prevline = find_next_newline_no_quit (prevline - 1, -1, &bytepos);
       pos = *compute_motion (prevline, 0,
                             lmargin,
                             0,
@@ -1974,7 +1963,7 @@ whether or not it is currently displayed in some window.  */)
   struct window *w;
   Lisp_Object old_buffer;
   EMACS_INT old_charpos IF_LINT (= 0), old_bytepos IF_LINT (= 0);
-  struct gcpro gcpro1, gcpro2, gcpro3;
+  struct gcpro gcpro1;
   Lisp_Object lcols = Qnil;
   double cols IF_LINT (= 0);
   void *itdata = NULL;
@@ -1988,20 +1977,16 @@ whether or not it is currently displayed in some window.  */)
     }
 
   CHECK_NUMBER (lines);
-  if (! NILP (window))
-    CHECK_WINDOW (window);
-  else
-    window = selected_window;
-  w = XWINDOW (window);
+  w = decode_live_window (window);
 
   old_buffer = Qnil;
-  GCPRO3 (old_buffer, old_charpos, old_bytepos);
+  GCPRO1 (old_buffer);
   if (XBUFFER (w->buffer) != current_buffer)
     {
       /* Set the window's buffer temporarily to the current buffer.  */
       old_buffer = w->buffer;
-      old_charpos = XMARKER (w->pointm)->charpos;
-      old_bytepos = XMARKER (w->pointm)->bytepos;
+      old_charpos = marker_position (w->pointm);
+      old_bytepos = marker_byte_position (w->pointm);
       wset_buffer (w, Fcurrent_buffer ());
       set_marker_both (w->pointm, w->buffer,
                       BUF_PT (current_buffer), BUF_PT_BYTE (current_buffer));
@@ -2034,7 +2019,11 @@ whether or not it is currently displayed in some window.  */)
          const char *s = SSDATA (it.string);
          const char *e = s + SBYTES (it.string);
 
-         disp_string_at_start_p = it.string_from_display_prop_p;
+         /* If it.area is anything but TEXT_AREA, we need not bother
+            about the display string, as it doesn't affect cursor
+            positioning.  */
+         disp_string_at_start_p =
+           it.string_from_display_prop_p && it.area == TEXT_AREA;
          while (s < e)
            {
              if (*s++ == '\n')