]> code.delx.au - gnu-emacs/blobdiff - src/indent.c
(mail-extr-all-top-level-domains): More domains.
[gnu-emacs] / src / indent.c
index ea0de2a10d6382741fcf431f7d24323515a3cc6a..b4592a2dddf8c9123a35515d22727ec8b970f212 100644 (file)
@@ -23,6 +23,7 @@ Boston, MA 02111-1307, USA.  */
 #include "lisp.h"
 #include "buffer.h"
 #include "charset.h"
+#include "category.h"
 #include "indent.h"
 #include "frame.h"
 #include "window.h"
@@ -208,8 +209,9 @@ skip_invisible (pos, next_boundary_p, to, window)
      int to;
      Lisp_Object window;
 {
-  Lisp_Object prop, position, end, overlay_limit, proplimit;
+  Lisp_Object prop, position, overlay_limit, proplimit;
   Lisp_Object buffer;
+  int end;
 
   XSETFASTINT (position, pos);
   XSETBUFFER (buffer, current_buffer);
@@ -239,8 +241,8 @@ 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 = Fnext_single_property_change (position, Qinvisible,
-                                         buffer, proplimit);
+      end = XFASTINT (Fnext_single_property_change (position, Qinvisible,
+                                                   buffer, proplimit));
       /* Don't put the boundary in the middle of multibyte form if
          there is no actual property change.  */
       if (end == pos + 100
@@ -248,7 +250,7 @@ skip_invisible (pos, next_boundary_p, to, window)
          && end < ZV)
        while (pos < end && !CHAR_HEAD_P (POS_ADDR (end)))
          end--;
-      *next_boundary_p = XFASTINT (end);
+      *next_boundary_p = end;
     }
   /* if the `invisible' property is set, we can skip to
      the next property change */
@@ -280,6 +282,7 @@ however, ^M is treated as end of line when `selective-display' is t.")
 
 /* Cancel any recorded value of the horizontal position.  */
 
+void
 invalidate_current_column ()
 {
   last_known_column_point = 0;
@@ -348,10 +351,12 @@ current_column ()
        col += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;
       else if (c >= 040 && c < 0177)
        col++;
-      else if (c == '\n')
-       break;
-      else if (c == '\r' && EQ (current_buffer->selective_display, Qt))
-       break;
+      else if (c == '\n'
+              || (c == '\r' && EQ (current_buffer->selective_display, Qt)))
+       {
+         ptr++;
+         break;
+       }
       else if (c == '\t')
        {
          if (tab_seen)
@@ -374,7 +379,7 @@ current_column ()
   if (ptr == BEGV_ADDR)
     current_column_bol_cache = BEGV;
   else
-    current_column_bol_cache = PTR_CHAR_POS ((ptr+1));
+    current_column_bol_cache = PTR_CHAR_POS (ptr);
   last_known_column = col;
   last_known_column_point = PT;
   last_known_column_modified = MODIFF;
@@ -677,6 +682,9 @@ position_indentation (pos)
        }
       switch (*p++)
        {
+       case 0240:
+         if (! NILP (current_buffer->enable_multibyte_characters))
+           return column;
        case ' ':
          column++;
          break;
@@ -684,7 +692,21 @@ position_indentation (pos)
          column += tab_width - column % tab_width;
          break;
        default:
-         return column;
+         if (ASCII_BYTE_P (p[-1])
+             || NILP (current_buffer->enable_multibyte_characters))
+           return column;
+         {
+           int pos = PTR_CHAR_POS (p - 1);
+           int c = FETCH_MULTIBYTE_CHAR (pos);
+           if (CHAR_HAS_CATEGORY (c, ' '))
+             {
+               column++;
+               INC_POS (pos);
+               p = POS_ADDR (pos);
+             }
+           else
+             return column;
+         }
        }
     }
 }
@@ -997,6 +1019,8 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
     {
       while (pos == next_boundary)
        {
+         int newpos;
+
          /* If the caller says that the screen position came from an earlier
             call to compute_motion, then we've already accounted for the
             overlay strings at point.  This is only true the first time
@@ -1020,7 +1044,12 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
             (but not necessarily all that there are here),
             and store in next_boundary the next position where
             we need to call skip_invisible.  */
-         pos = skip_invisible (pos, &next_boundary, to, window);
+         newpos = skip_invisible (pos, &next_boundary, to, window);
+
+         if (newpos >= to)
+           goto after_loop;
+
+         pos = newpos;
        }
 
       /* Handle right margin.  */
@@ -1144,7 +1173,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
       if (vpos > tovpos || vpos == tovpos && hpos >= tohpos)
        {
          if (contin_hpos && prev_hpos == 0
-             && (contin_hpos == width || wide_column))
+             && ((hpos > tohpos && contin_hpos == width) || wide_column))
            { /* Line breaks because we can't put the character at the
                 previous line any more.  It is not the multi-column
                 character continued in middle.  Go back to previous
@@ -1224,7 +1253,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
              /* Is this character part of the current run?  If so, extend
                 the run.  */
              if (pos - 1 == width_run_end
-                 && width_table[c] == width_run_width)
+                 && XFASTINT (width_table[c]) == width_run_width)
                width_run_end = pos;
 
              /* The previous run is over, since this is a character at a
@@ -1240,13 +1269,14 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
                                       width_run_start, width_run_end);
 
                  /* Start recording a new width run.  */
-                 width_run_width = width_table[c];
+                 width_run_width = XFASTINT (width_table[c]);
                  width_run_start = pos - 1;
                  width_run_end = pos;
                }
            }
 
-         if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
+         if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c))
+             && ! (multibyte && BASE_LEADING_CODE_P (c)))
            hpos += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;
          else if (c >= 040 && c < 0177)
            hpos++;
@@ -1261,21 +1291,26 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
            {
              if (selective > 0 && indented_beyond_p (pos, selective))
                {
-                 /* Skip any number of invisible lines all at once */
-                 do
-                   pos = find_before_next_newline (pos, to, 1) + 1;
-                 while (pos < to
-                        && indented_beyond_p (pos, selective));
-                 /* Allow for the " ..." that is displayed for them. */
-                 if (selective_rlen)
+                 /* If (pos == to), we don't have to take care of
+                   selective display.  */
+                 if (pos < to)
                    {
-                     hpos += selective_rlen;
-                     if (hpos >= width)
-                       hpos = width;
+                     /* Skip any number of invisible lines all at once */
+                     do
+                       pos = find_before_next_newline (pos, to, 1) + 1;
+                     while (pos < to
+                            && indented_beyond_p (pos, selective));
+                     /* Allow for the " ..." that is displayed for them. */
+                     if (selective_rlen)
+                       {
+                         hpos += selective_rlen;
+                         if (hpos >= width)
+                           hpos = width;
+                       }
+                     --pos;
+                     /* We have skipped the invis text, but not the
+                       newline after.  */
                    }
-                 --pos;
-                 /* We have skipped the invis text, but not the
-                    newline after.  */
                }
              else
                {
@@ -1295,7 +1330,8 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
              /* In selective display mode,
                 everything from a ^M to the end of the line is invisible.
                 Stop *before* the real newline.  */
-             pos = find_before_next_newline (pos, to, 1);
+             if (pos < to)
+               pos = find_before_next_newline (pos, to, 1);
              /* If we just skipped next_boundary,
                 loop around in the main while
                 and handle it.  */
@@ -1313,48 +1349,44 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width,
            {
              /* Start of multi-byte form.  */
              unsigned char *ptr;
+             int len, actual_len;
 
              pos--;            /* rewind POS */
-             ptr = POS_ADDR (pos);
 
-             if (c == LEADING_CODE_COMPOSITION)
-               {
-                 int cmpchar_id = str_cmpchar_id (ptr, next_boundary - pos);
+             ptr = (((pos) >= GPT ? GAP_SIZE : 0) + (pos) + BEG_ADDR - 1);
+             len = ((pos) >= GPT ? ZV : GPT) - (pos);
 
-                 if (cmpchar_id >= 0)
-                   {
-                     if (cmpchar_table[cmpchar_id]->width >= 2)
-                       wide_column = 1;
-                     hpos += cmpchar_table[cmpchar_id]->width;
-                     pos += cmpchar_table[cmpchar_id]->len;
-                   }
-                 else
-                   {           /* invalid composite character */
-                     hpos += 4;
-                     pos ++;
-                   }
+             c = STRING_CHAR_AND_LENGTH (ptr, len, actual_len);
+
+             if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
+               hpos += XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;
+             else if (actual_len == 1)
+               hpos += 4;
+             else if (COMPOSITE_CHAR_P (c))
+               {
+                 int id = COMPOSITE_CHAR_ID (c);
+                 int width = (id < n_cmpchars) ? cmpchar_table[id]->width : 0;
+                 hpos += width;
+                 if (width > 1)
+                   wide_column = 1;
                }
              else
                {
-                 /* Here, we check that the following bytes are valid
-                    constituents of multi-byte form.  */
-                 int len = BYTES_BY_CHAR_HEAD (c), i;
-
-                 for (i = 1, ptr++; i < len; i++, ptr++)
-                   /* We don't need range checking for PTR because
-                      there are anchors ('\0') both at GPT and Z.  */
-                   if (CHAR_HEAD_P (ptr)) break;
-                 if (i < len)
-                   hpos += 4, pos++;
-                 else
-                   hpos += WIDTH_BY_CHAR_HEAD (c), pos += i, wide_column = 1;
+                 int width = WIDTH_BY_CHAR_HEAD (*ptr);
+                 hpos += width;
+                 if (width > 1)
+                   wide_column = 1;
                }
+
+             pos += actual_len;
            }
          else
            hpos += (ctl_arrow && c < 0200) ? 2 : 4;
        }
     }
 
+ after_loop:
+
   /* Remember any final width run in the cache.  */
   if (current_buffer->width_run_cache
       && width_run_width == 1