(linenum→info "unix/slp.c:2238")

emacs/22.1/src/indent.c

    1: /* Indentation functions.
    2:    Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1998, 2000, 2001,
    3:                  2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    4: 
    5: This file is part of GNU Emacs.
    6: 
    7: GNU Emacs is free software; you can redistribute it and/or modify
    8: it under the terms of the GNU General Public License as published by
    9: the Free Software Foundation; either version 2, or (at your option)
   10: any later version.
   11: 
   12: GNU Emacs is distributed in the hope that it will be useful,
   13: but WITHOUT ANY WARRANTY; without even the implied warranty of
   14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15: GNU General Public License for more details.
   16: 
   17: You should have received a copy of the GNU General Public License
   18: along with GNU Emacs; see the file COPYING.  If not, write to
   19: the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   20: Boston, MA 02110-1301, USA.  */
   21: 
   22: #include <config.h>
   23: #include "lisp.h"
   24: #include "buffer.h"
   25: #include "charset.h"
   26: #include "category.h"
   27: #include "indent.h"
   28: #include "keyboard.h"
   29: #include "frame.h"
   30: #include "window.h"
   31: #include "termchar.h"
   32: #include "termopts.h"
   33: #include "disptab.h"
   34: #include "intervals.h"
   35: #include "region-cache.h"
   36: 
   37: /* Indentation can insert tabs if this is non-zero;
   38:    otherwise always uses spaces.  */
   39: 
   40: int indent_tabs_mode;
   41: 
   42: #define CR 015
   43: 
   44: /* These three values memorize the current column to avoid recalculation.  */
   45: 
   46: /* Last value returned by current_column.
   47:    Some things in set last_known_column_point to -1
   48:    to mark the memorized value as invalid.  */
   49: 
   50: double last_known_column;
   51: 
   52: /* Value of point when current_column was called.  */
   53: 
   54: int last_known_column_point;
   55: 
   56: /* Value of MODIFF when current_column was called.  */
   57: 
   58: int last_known_column_modified;
   59: 
   60: static double current_column_1 P_ ((void));
   61: static double position_indentation P_ ((int));
   62: 
   63: /* Cache of beginning of line found by the last call of
   64:    current_column. */
   65: 
   66: int current_column_bol_cache;
   67: 
   68: /* Get the display table to use for the current buffer.  */
   69: 
   70: struct Lisp_Char_Table *
   71: buffer_display_table ()
   72: {
   73:   Lisp_Object thisbuf;
   74: 
   75:   thisbuf = current_buffer->display_table;
   76:   if (DISP_TABLE_P (thisbuf))
   77:     return XCHAR_TABLE (thisbuf);
   78:   if (DISP_TABLE_P (Vstandard_display_table))
   79:     return XCHAR_TABLE (Vstandard_display_table);
   80:   return 0;
   81: }
   82: ^L
   83: /* Width run cache considerations.  */
   84: 
   85: /* Return the width of character C under display table DP.  */
   86: 
   87: static int
   88: character_width (c, dp)
   89:      int c;
   90:      struct Lisp_Char_Table *dp;
   91: {
   92:   Lisp_Object elt;
   93: 
   94:   /* These width computations were determined by examining the cases
   95:      in display_text_line.  */
   96: 
   97:   /* Everything can be handled by the display table, if it's
   98:      present and the element is right.  */
   99:   if (dp && (elt = DISP_CHAR_VECTOR (dp, c), VECTORP (elt)))
  100:     return XVECTOR (elt)->size;
  101: 
  102:   /* Some characters are special.  */
  103:   if (c == '\n' || c == '\t' || c == '\015')
  104:     return 0;
  105: 
  106:   /* Printing characters have width 1.  */
  107:   else if (c >= 040 && c < 0177)
  108:     return 1;
  109: 
  110:   /* Everybody else (control characters, metacharacters) has other
  111:      widths.  We could return their actual widths here, but they
  112:      depend on things like ctl_arrow and crud like that, and they're
  113:      not very common at all.  So we'll just claim we don't know their
  114:      widths.  */
  115:   else
  116:     return 0;
  117: }
  118: 
  119: /* Return true iff the display table DISPTAB specifies the same widths
  120:    for characters as WIDTHTAB.  We use this to decide when to
  121:    invalidate the buffer's width_run_cache.  */
  122: 
  123: int
  124: disptab_matches_widthtab (disptab, widthtab)
  125:      struct Lisp_Char_Table *disptab;
  126:      struct Lisp_Vector *widthtab;
  127: {
  128:   int i;
  129: 
  130:   if (widthtab->size != 256)
  131:     abort ();
  132: 
  133:   for (i = 0; i < 256; i++)
  134:     if (character_width (i, disptab)
  135:         != XFASTINT (widthtab->contents[i]))
  136:       return 0;
  137: 
  138:   return 1;
  139: }
  140: 
  141: /* Recompute BUF's width table, using the display table DISPTAB.  */
  142: 
  143: void
  144: recompute_width_table (buf, disptab)
  145:      struct buffer *buf;
  146:      struct Lisp_Char_Table *disptab;
  147: {
  148:   int i;
  149:   struct Lisp_Vector *widthtab;
  150: 
  151:   if (!VECTORP (buf->width_table))
  152:     buf->width_table = Fmake_vector (make_number (256), make_number (0));
  153:   widthtab = XVECTOR (buf->width_table);
  154:   if (widthtab->size != 256)
  155:     abort ();
  156: 
  157:   for (i = 0; i < 256; i++)
  158:     XSETFASTINT (widthtab->contents[i], character_width (i, disptab));
  159: }
  160: 
  161: /* Allocate or free the width run cache, as requested by the current
  162:    state of current_buffer's cache_long_line_scans variable.  */
  163: 
  164: static void
  165: width_run_cache_on_off ()
  166: {
  167:   if (NILP (current_buffer->cache_long_line_scans)
  168:       /* And, for the moment, this feature doesn't work on multibyte
  169:          characters.  */
  170:       || !NILP (current_buffer->enable_multibyte_characters))
  171:     {
  172:       /* It should be off.  */
  173:       if (current_buffer->width_run_cache)
  174:         {
  175:           free_region_cache (current_buffer->width_run_cache);
  176:           current_buffer->width_run_cache = 0;
  177:           current_buffer->width_table = Qnil;
  178:         }
  179:     }
  180:   else
  181:     {
  182:       /* It should be on.  */
  183:       if (current_buffer->width_run_cache == 0)
  184:         {
  185:           current_buffer->width_run_cache = new_region_cache ();
  186:           recompute_width_table (current_buffer, buffer_display_table ());
  187:         }
  188:     }
  189: }
  190: 
  191: ^L
  192: /* Skip some invisible characters starting from POS.
  193:    This includes characters invisible because of text properties
  194:    and characters invisible because of overlays.
  195: 
  196:    If position POS is followed by invisible characters,
  197:    skip some of them and return the position after them.
  198:    Otherwise return POS itself.
  199: 
  200:    Set *NEXT_BOUNDARY_P to the next position at which
  201:    it will be necessary to call this function again.
  202: 
  203:    Don't scan past TO, and don't set *NEXT_BOUNDARY_P
  204:    to a value greater than TO.
  205: 
  206:    If WINDOW is non-nil, and this buffer is displayed in WINDOW,
  207:    take account of overlays that apply only in WINDOW.
  208: 
  209:    We don't necessarily skip all the invisible characters after POS
  210:    because that could take a long time.  We skip a reasonable number
  211:    which can be skipped quickly.  If there might be more invisible
  212:    characters immediately following, then *NEXT_BOUNDARY_P
  213:    will equal the return value.  */
  214: 
  215: int
  216: skip_invisible (pos, next_boundary_p, to, window)
  217:      int pos;
  218:      int *next_boundary_p;
  219:      int to;
  220:      Lisp_Object window;
  221: {
  222:   Lisp_Object prop, position, overlay_limit, proplimit;
  223:   Lisp_Object buffer, tmp;
  224:   int end, inv_p;
  225: 
  226:   XSETFASTINT (position, pos);
  227:   XSETBUFFER (buffer, current_buffer);
  228: 
  229:   /* Give faster response for overlay lookup near POS.  */
  230:   recenter_overlay_lists (current_buffer, pos);
  231: 
  232:   /* We must not advance farther than the next overlay change.
  233:      The overlay change might change the invisible property;
  234:      or there might be overlay strings to be displayed there.  */
  235:   overlay_limit = Fnext_overlay_change (position);
  236:   /* As for text properties, this gives a lower bound
  237:      for where the invisible text property could change.  */
  238:   proplimit = Fnext_property_change (position, buffer, Qt);
  239:   if (XFASTINT (overlay_limit) < XFASTINT (proplimit))
  240:     proplimit = overlay_limit;
  241:   /* PROPLIMIT is now a lower bound for the next change
  242:      in invisible status.  If that is plenty far away,
  243:      use that lower bound.  */
  244:   if (XFASTINT (proplimit) > pos + 100 || XFASTINT (proplimit) >= to)
  245:     *next_boundary_p = XFASTINT (proplimit);
  246:   /* Otherwise, scan for the next `invisible' property change.  */
  247:   else
  248:     {
  249:       /* Don't scan terribly far.  */
  250:       XSETFASTINT (proplimit, min (pos + 100, to));
  251:       /* No matter what. don't go past next overlay change.  */
  252:       if (XFASTINT (overlay_limit) < XFASTINT (proplimit))
  253:         proplimit = overlay_limit;
  254:       tmp = Fnext_single_property_change (position, Qinvisible,
  255:                                           buffer, proplimit);
  256:       end = XFASTINT (tmp);
  257: #if 0
  258:       /* Don't put the boundary in the middle of multibyte form if
  259:          there is no actual property change.  */
  260:       if (end == pos + 100
  261:           && !NILP (current_buffer->enable_multibyte_characters)
  262:           && end < ZV)
  263:         while (pos < end && !CHAR_HEAD_P (POS_ADDR (end)))
  264:           end--;
  265: #endif
  266:       *next_boundary_p = end;
  267:     }
  268:   /* if the `invisible' property is set, we can skip to
  269:      the next property change */
  270:   prop = Fget_char_property (position, Qinvisible,
  271:                              (!NILP (window)
  272:                               && EQ (XWINDOW (window)->buffer, buffer))
  273:                              ? window : buffer);
  274:   inv_p = TEXT_PROP_MEANS_INVISIBLE (prop);
  275:   /* When counting columns (window == nil), don't skip over ellipsis text.  */
  276:   if (NILP (window) ? inv_p == 1 : inv_p)
  277:     return *next_boundary_p;
  278:   return pos;
  279: }
  280: ^L
  281: /* If a composition starts at POS/POS_BYTE and it doesn't stride over
  282:    POINT, set *LEN / *LEN_BYTE to the character and byte lengths, *WIDTH
  283:    to the width, and return 1.  Otherwise, return 0.  */
  284: 
  285: static int
  286: check_composition (pos, pos_byte, point, len, len_byte, width)
  287:      int pos, pos_byte, point;
  288:      int *len, *len_byte, *width;
  289: {
  290:   Lisp_Object prop;
  291:   int start, end;
  292:   int id;
  293: 
  294:   if (! find_composition (pos, -1, &start, &end, &prop, Qnil)
  295:       || pos != start || point < end
  296:       || !COMPOSITION_VALID_P (start, end, prop))
  297:     return 0;
  298:   if ((id = get_composition_id (pos, pos_byte, end - pos, prop, Qnil)) < 0)
  299:     return 0;
  300: 
  301:   *len = COMPOSITION_LENGTH (prop);
  302:   *len_byte = CHAR_TO_BYTE (end) - pos_byte;
  303:   *width = composition_table[id]->width;
  304:   return 1;
  305: }
  306: ^L
  307: /* Set variables WIDTH and BYTES for a multibyte sequence starting at P.
  308: 
  309:    DP is a display table or NULL.
  310: 
  311:    This macro is used in current_column_1, Fmove_to_column, and
  312:    compute_motion.  */
  313: 
  314: #define MULTIBYTE_BYTES_WIDTH(p, dp)                                    \
  315:   do {                                                                  \
  316:     int c;                                                              \
  317:                                                                         \
  318:     wide_column = 0;                                                    \
  319:     c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, bytes);        \
  320:     if (BYTES_BY_CHAR_HEAD (*p) != bytes)                               \
  321:       width = bytes * 4;                                                \
  322:     else                                                                \
  323:       {                                                                 \
  324:         if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))             \
  325:           width = XVECTOR (DISP_CHAR_VECTOR (dp, c))->size;            \
  326:         else                                                           \
  327:           width = WIDTH_BY_CHAR_HEAD (*p);                             \
  328:         if (width > 1)                                                 \
  329:           wide_column = width;                                         \
  330:       }                                                                 \
  331:   } while (0)
  332: 
  333: 
  334: DEFUN ("current-column", Fcurrent_column, Scurrent_column, 0, 0, 0,
  335:        doc: /* Return the horizontal position of point.  Beginning of line is column 0.
  336: This is calculated by adding together the widths of all the displayed
  337: representations of the character between the start of the previous line
  338: and point (eg. control characters will have a width of 2 or 4, tabs
  339: will have a variable width).
  340: Ignores finite width of frame, which means that this function may return
  341: values greater than (frame-width).
  342: Whether the line is visible (if `selective-display' is t) has no effect;
  343: however, ^M is treated as end of line when `selective-display' is t.
  344: Text that has an invisible property is considered as having width 0, unless
  345: `buffer-invisibility-spec' specifies that it is replaced by an ellipsis.  */)
  346:      ()
  347: {
  348:   Lisp_Object temp;
  349:   XSETFASTINT (temp, (int) current_column ()); /* iftc */
  350:   return temp;
  351: }
  352: 
  353: /* Cancel any recorded value of the horizontal position.  */
  354: 
  355: void
  356: invalidate_current_column ()
  357: {
  358:   last_known_column_point = 0;
  359: }
  360: 
  361: double
  362: current_column ()
  363: {
  364:   register int col;
  365:   register unsigned char *ptr, *stop;
  366:   register int tab_seen;
  367:   int post_tab;
  368:   register int c;
  369:   register int tab_width = XINT (current_buffer->tab_width);
  370:   int ctl_arrow = !NILP (current_buffer->ctl_arrow);
  371:   register struct Lisp_Char_Table *dp = buffer_display_table ();
  372: 
  373:   if (PT == last_known_column_point
  374:       && MODIFF == last_known_column_modified)
  375:     return last_known_column;
  376: 
  377:   /* If the buffer has overlays, text properties,
  378:      or multibyte characters, use a more general algorithm.  */
  379:   if (BUF_INTERVALS (current_buffer)
  380:       || current_buffer->overlays_before
  381:       || current_buffer->overlays_after
  382:       || Z != Z_BYTE)
  383:     return current_column_1 ();
  384: 
  385:   /* Scan backwards from point to the previous newline,
  386:      counting width.  Tab characters are the only complicated case.  */
  387: 
  388:   /* Make a pointer for decrementing through the chars before point.  */
  389:   ptr = BYTE_POS_ADDR (PT_BYTE - 1) + 1;
  390:   /* Make a pointer to where consecutive chars leave off,
  391:      going backwards from point.  */
  392:   if (PT == BEGV)
  393:     stop = ptr;
  394:   else if (PT <= GPT || BEGV > GPT)
  395:     stop = BEGV_ADDR;
  396:   else
  397:     stop = GAP_END_ADDR;
  398: 
  399:   if (tab_width <= 0 || tab_width > 1000)
  400:     tab_width = 8;
  401: 
  402:   col = 0, tab_seen = 0, post_tab = 0;
  403: 
  404:   while (1)
  405:     {
  406:       EMACS_INT i, n;
  407:       Lisp_Object charvec;
  408: 
  409:       if (ptr == stop)
  410:         {
  411:           /* We stopped either for the beginning of the buffer
  412:              or for the gap.  */
  413:           if (ptr == BEGV_ADDR)
  414:             break;
  415: 
  416:           /* It was the gap.  Jump back over it.  */
  417:           stop = BEGV_ADDR;
  418:           ptr = GPT_ADDR;
  419: 
  420:           /* Check whether that brings us to beginning of buffer.  */
  421:           if (BEGV >= GPT)
  422:             break;
  423:         }
  424: 
  425:       c = *--ptr;
  426: 
  427:       if (dp && VECTORP (DISP_CHAR_VECTOR (dp, c)))
  428:         {
  429:           charvec = DISP_CHAR_VECTOR (dp, c);
  430:           n = ASIZE (charvec);
  431:         }
  432:       else
  433:         {
  434:           charvec = Qnil;
  435:           n = 1;
  436:         }
  437: 
  438:       for (i = n - 1; i >= 0; --i)
  439:         {
  440:           if (VECTORP (charvec))
  441:             {
  442:               /* This should be handled the same as
  443:                  next_element_from_display_vector does it.  */
  444:               Lisp_Object entry = AREF (charvec, i);
  445: 
  446:               if (INTEGERP (entry)
  447:                   && GLYPH_CHAR_VALID_P (XFASTINT (entry)))
  448:                 c = FAST_GLYPH_CHAR (XFASTINT (entry));
  449:               else
  450:                 c = ' ';
  451:             }
  452: 
  453:           if (c >= 040 && c < 0177)
  454:             col++;
  455:           else if (c == '\n'
  456:                    || (c == '\r'
  457:                        && EQ (current_buffer->selective_display, Qt)))
  458:             {
  459:               ptr++;
  460:               goto start_of_line_found;
  461:             }
  462:           else if (c == '\t')
  463:             {
  464:               if (tab_seen)
  465:                 col = ((col + tab_width) / tab_width) * tab_width;
  466: 
  467:               post_tab += col;
  468:               col = 0;
  469:               tab_seen = 1;
  470:             }
  471:           else if (VECTORP (charvec))
  472:             /* With a display table entry, C is displayed as is, and
  473:                not displayed as \NNN or as ^N.  If C is a single-byte
  474:                character, it takes one column.  If C is multi-byte in
  475:                an unibyte buffer, it's translated to unibyte, so it
  476:                also takes one column.  */
  477:             ++col;
  478:           else
  479:             col += (ctl_arrow && c < 0200) ? 2 : 4;
  480:         }
  481:     }
  482: 
  483:  start_of_line_found:
  484: 
  485:   if (tab_seen)
  486:     {
  487:       col = ((col + tab_width) / tab_width) * tab_width;
  488:       col += post_tab;
  489:     }
  490: 
  491:   if (ptr == BEGV_ADDR)
  492:     current_column_bol_cache = BEGV;
  493:   else
  494:     current_column_bol_cache = BYTE_TO_CHAR (PTR_BYTE_POS (ptr));
  495: 
  496:   last_known_column = col;
  497:   last_known_column_point = PT;
  498:   last_known_column_modified = MODIFF;
  499: 
  500:   return col;
  501: }
  502: ^L
  503: /* Return the column number of position POS
  504:    by scanning forward from the beginning of the line.
  505:    This function handles characters that are invisible
  506:    due to text properties or overlays.  */
  507: 
  508: static double
  509: current_column_1 ()
  510: {
  511:   register int tab_width = XINT (current_buffer->tab_width);
  512:   register int ctl_arrow = !NILP (current_buffer->ctl_arrow);
  513:   register struct Lisp_Char_Table *dp = buffer_display_table ();
  514:   int multibyte = !NILP (current_buffer->enable_multibyte_characters);
  515: 
  516:   /* Start the scan at the beginning of this line with column number 0.  */
  517:   register int col = 0;
  518:   int scan, scan_byte;
  519:   int next_boundary;
  520:   int opoint = PT, opoint_byte = PT_BYTE;
  521: 
  522:   scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1);
  523:   current_column_bol_cache = PT;
  524:   scan = PT, scan_byte = PT_BYTE;
  525:   SET_PT_BOTH (opoint, opoint_byte);
  526:   next_boundary = scan;
  527: 
  528:   if (tab_width <= 0 || tab_width > 1000) tab_width = 8;
  529: 
  530:   /* Scan forward to the target position.  */
  531:   while (scan < opoint)
  532:     {
  533:       int c;
  534: 
  535:       /* Occasionally we may need to skip invisible text.  */
  536:       while (scan == next_boundary)
  537:         {
  538:           int old_scan = scan;
  539:           /* This updates NEXT_BOUNDARY to the next place
  540:              where we might need to skip more invisible text.  */
  541:           scan = skip_invisible (scan, &next_boundary, opoint, Qnil);
  542:           if (scan >= opoint)
  543:             goto endloop;
  544:           if (scan != old_scan)
  545:             scan_byte = CHAR_TO_BYTE (scan);
  546:         }
  547: 
  548:       /* Check composition sequence.  */
  549:       {
  550:         int len, len_byte, width;
  551: 
  552:         if (check_composition (scan, scan_byte, opoint,
  553:                                &len, &len_byte, &width))
  554:           {
  555:             scan += len;
  556:             scan_byte += len_byte;
  557:             if (scan <= opoint)
  558:               col += width;
  559:             continue;
  560:           }
  561:       }
  562: 
  563:       c = FETCH_BYTE (scan_byte);
  564: 
  565:       if (dp != 0
  566:           && ! (multibyte && BASE_LEADING_CODE_P (c))
  567:           && VECTORP (DISP_CHAR_VECTOR (dp, c)))
  568:         {
  569:           Lisp_Object charvec;
  570:           EMACS_INT i, n;
  571: 
  572:           /* This character is displayed using a vector of glyphs.
  573:              Update the column based on those glyphs.  */
  574: 
  575:           charvec = DISP_CHAR_VECTOR (dp, c);
  576:           n = ASIZE (charvec);
  577: 
  578:           for (i = 0; i < n; i++)
  579:             {
  580:               /* This should be handled the same as
  581:                  next_element_from_display_vector does it.  */
  582:               Lisp_Object entry;
  583:               entry = AREF (charvec, i);
  584: 
  585:               if (INTEGERP (entry)
  586:                   && GLYPH_CHAR_VALID_P (XFASTINT (entry)))
  587:                 c = FAST_GLYPH_CHAR (XFASTINT (entry));
  588:               else
  589:                 c = ' ';
  590: 
  591:               if (c == '\n')
  592:                 goto endloop;
  593:               if (c == '\r' && EQ (current_buffer->selective_display, Qt))
  594:                 goto endloop;
  595:               if (c == '\t')
  596:                 {
  597:                   col += tab_width;
  598:                   col = col / tab_width * tab_width;
  599:                 }
  600:               else
  601:                 ++col;
  602:             }
  603:         }
  604:       else
  605:         {
  606:           /* The display table says nothing for this character.
  607:              Display it as itself.  */
  608: 
  609:           if (c == '\n')
  610:             goto endloop;
  611:           if (c == '\r' && EQ (current_buffer->selective_display, Qt))
  612:             goto endloop;
<