diff options
Diffstat (limited to 'src/indent.c')
| -rw-r--r-- | src/indent.c | 160 |
1 files changed, 83 insertions, 77 deletions
diff --git a/src/indent.c b/src/indent.c index 02d99d14ded..a1fcd2b1018 100644 --- a/src/indent.c +++ b/src/indent.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Indentation functions. | 1 | /* Indentation functions. |
| 2 | Copyright (C) 1985-1988, 1993-1995, 1998, 2000-2011 | 2 | Copyright (C) 1985-1988, 1993-1995, 1998, 2000-2012 |
| 3 | Free Software Foundation, Inc. | 3 | Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| @@ -56,7 +56,7 @@ EMACS_INT last_known_column_point; | |||
| 56 | static int last_known_column_modified; | 56 | static int last_known_column_modified; |
| 57 | 57 | ||
| 58 | static EMACS_INT current_column_1 (void); | 58 | static EMACS_INT current_column_1 (void); |
| 59 | static EMACS_INT position_indentation (int); | 59 | static EMACS_INT position_indentation (ptrdiff_t); |
| 60 | 60 | ||
| 61 | /* Cache of beginning of line found by the last call of | 61 | /* Cache of beginning of line found by the last call of |
| 62 | current_column. */ | 62 | current_column. */ |
| @@ -284,7 +284,7 @@ skip_invisible (EMACS_INT pos, EMACS_INT *next_boundary_p, EMACS_INT to, Lisp_Ob | |||
| 284 | else \ | 284 | else \ |
| 285 | { \ | 285 | { \ |
| 286 | if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, ch))) \ | 286 | if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, ch))) \ |
| 287 | width = ASIZE (DISP_CHAR_VECTOR (dp, ch)); \ | 287 | width = sanitize_char_width (ASIZE (DISP_CHAR_VECTOR (dp, ch))); \ |
| 288 | else \ | 288 | else \ |
| 289 | width = CHAR_WIDTH (ch); \ | 289 | width = CHAR_WIDTH (ch); \ |
| 290 | } \ | 290 | } \ |
| @@ -318,15 +318,6 @@ invalidate_current_column (void) | |||
| 318 | last_known_column_point = 0; | 318 | last_known_column_point = 0; |
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | /* Return a non-outlandish value for the tab width. */ | ||
| 322 | |||
| 323 | static int | ||
| 324 | sane_tab_width (void) | ||
| 325 | { | ||
| 326 | EMACS_INT n = XFASTINT (BVAR (current_buffer, tab_width)); | ||
| 327 | return 0 < n && n <= 1000 ? n : 8; | ||
| 328 | } | ||
| 329 | |||
| 330 | EMACS_INT | 321 | EMACS_INT |
| 331 | current_column (void) | 322 | current_column (void) |
| 332 | { | 323 | { |
| @@ -335,7 +326,7 @@ current_column (void) | |||
| 335 | register int tab_seen; | 326 | register int tab_seen; |
| 336 | EMACS_INT post_tab; | 327 | EMACS_INT post_tab; |
| 337 | register int c; | 328 | register int c; |
| 338 | int tab_width = sane_tab_width (); | 329 | int tab_width = SANE_TAB_WIDTH (current_buffer); |
| 339 | int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow)); | 330 | int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow)); |
| 340 | register struct Lisp_Char_Table *dp = buffer_display_table (); | 331 | register struct Lisp_Char_Table *dp = buffer_display_table (); |
| 341 | 332 | ||
| @@ -480,7 +471,7 @@ check_display_width (EMACS_INT pos, EMACS_INT col, EMACS_INT *endpos) | |||
| 480 | if (CONSP (val = get_char_property_and_overlay | 471 | if (CONSP (val = get_char_property_and_overlay |
| 481 | (make_number (pos), Qdisplay, Qnil, &overlay)) | 472 | (make_number (pos), Qdisplay, Qnil, &overlay)) |
| 482 | && EQ (Qspace, XCAR (val))) | 473 | && EQ (Qspace, XCAR (val))) |
| 483 | { /* FIXME: Use calc_pixel_width_or_height, as in term.c. */ | 474 | { /* FIXME: Use calc_pixel_width_or_height. */ |
| 484 | Lisp_Object plist = XCDR (val), prop; | 475 | Lisp_Object plist = XCDR (val), prop; |
| 485 | int width = -1; | 476 | int width = -1; |
| 486 | 477 | ||
| @@ -515,7 +506,7 @@ check_display_width (EMACS_INT pos, EMACS_INT col, EMACS_INT *endpos) | |||
| 515 | static void | 506 | static void |
| 516 | scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol) | 507 | scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol) |
| 517 | { | 508 | { |
| 518 | int tab_width = sane_tab_width (); | 509 | int tab_width = SANE_TAB_WIDTH (current_buffer); |
| 519 | register int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow)); | 510 | register int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow)); |
| 520 | register struct Lisp_Char_Table *dp = buffer_display_table (); | 511 | register struct Lisp_Char_Table *dp = buffer_display_table (); |
| 521 | int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); | 512 | int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); |
| @@ -725,15 +716,14 @@ current_column_1 (void) | |||
| 725 | If END is nil, that stands for the end of STRING. */ | 716 | If END is nil, that stands for the end of STRING. */ |
| 726 | 717 | ||
| 727 | static double | 718 | static double |
| 728 | string_display_width (string, beg, end) | 719 | string_display_width (Lisp_Object string, Lisp_Object beg, Lisp_Object end) |
| 729 | Lisp_Object string, beg, end; | ||
| 730 | { | 720 | { |
| 731 | register int col; | 721 | register int col; |
| 732 | register unsigned char *ptr, *stop; | 722 | register unsigned char *ptr, *stop; |
| 733 | register int tab_seen; | 723 | register int tab_seen; |
| 734 | int post_tab; | 724 | int post_tab; |
| 735 | register int c; | 725 | register int c; |
| 736 | int tab_width = sane_tab_width (); | 726 | int tab_width = SANE_TAB_WIDTH (current_buffer); |
| 737 | int ctl_arrow = !NILP (current_buffer->ctl_arrow); | 727 | int ctl_arrow = !NILP (current_buffer->ctl_arrow); |
| 738 | register struct Lisp_Char_Table *dp = buffer_display_table (); | 728 | register struct Lisp_Char_Table *dp = buffer_display_table (); |
| 739 | int b, e; | 729 | int b, e; |
| @@ -809,7 +799,7 @@ The return value is COLUMN. */) | |||
| 809 | { | 799 | { |
| 810 | EMACS_INT mincol; | 800 | EMACS_INT mincol; |
| 811 | register EMACS_INT fromcol; | 801 | register EMACS_INT fromcol; |
| 812 | int tab_width = sane_tab_width (); | 802 | int tab_width = SANE_TAB_WIDTH (current_buffer); |
| 813 | 803 | ||
| 814 | CHECK_NUMBER (column); | 804 | CHECK_NUMBER (column); |
| 815 | if (NILP (minimum)) | 805 | if (NILP (minimum)) |
| @@ -865,10 +855,10 @@ following any initial whitespace. */) | |||
| 865 | } | 855 | } |
| 866 | 856 | ||
| 867 | static EMACS_INT | 857 | static EMACS_INT |
| 868 | position_indentation (register int pos_byte) | 858 | position_indentation (ptrdiff_t pos_byte) |
| 869 | { | 859 | { |
| 870 | register EMACS_INT column = 0; | 860 | register EMACS_INT column = 0; |
| 871 | int tab_width = sane_tab_width (); | 861 | int tab_width = SANE_TAB_WIDTH (current_buffer); |
| 872 | register unsigned char *p; | 862 | register unsigned char *p; |
| 873 | register unsigned char *stop; | 863 | register unsigned char *stop; |
| 874 | unsigned char *start; | 864 | unsigned char *start; |
| @@ -1117,7 +1107,7 @@ compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_ | |||
| 1117 | register EMACS_INT pos; | 1107 | register EMACS_INT pos; |
| 1118 | EMACS_INT pos_byte; | 1108 | EMACS_INT pos_byte; |
| 1119 | register int c = 0; | 1109 | register int c = 0; |
| 1120 | int tab_width = sane_tab_width (); | 1110 | int tab_width = SANE_TAB_WIDTH (current_buffer); |
| 1121 | register int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow)); | 1111 | register int ctl_arrow = !NILP (BVAR (current_buffer, ctl_arrow)); |
| 1122 | register struct Lisp_Char_Table *dp = window_display_table (win); | 1112 | register struct Lisp_Char_Table *dp = window_display_table (win); |
| 1123 | EMACS_INT selective | 1113 | EMACS_INT selective |
| @@ -1433,7 +1423,7 @@ compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_ | |||
| 1433 | the text character-by-character. */ | 1423 | the text character-by-character. */ |
| 1434 | if (current_buffer->width_run_cache && pos >= next_width_run) | 1424 | if (current_buffer->width_run_cache && pos >= next_width_run) |
| 1435 | { | 1425 | { |
| 1436 | EMACS_INT run_end; | 1426 | ptrdiff_t run_end; |
| 1437 | int common_width | 1427 | int common_width |
| 1438 | = region_cache_forward (current_buffer, | 1428 | = region_cache_forward (current_buffer, |
| 1439 | current_buffer->width_run_cache, | 1429 | current_buffer->width_run_cache, |
| @@ -1553,7 +1543,7 @@ compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_ | |||
| 1553 | n = 1; | 1543 | n = 1; |
| 1554 | } | 1544 | } |
| 1555 | 1545 | ||
| 1556 | for (i = n - 1; i >= 0; --i) | 1546 | for (i = 0; i < n; ++i) |
| 1557 | { | 1547 | { |
| 1558 | if (VECTORP (charvec)) | 1548 | if (VECTORP (charvec)) |
| 1559 | { | 1549 | { |
| @@ -1685,7 +1675,7 @@ compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_ | |||
| 1685 | val_compute_motion.prevhpos = contin_hpos; | 1675 | val_compute_motion.prevhpos = contin_hpos; |
| 1686 | else | 1676 | else |
| 1687 | val_compute_motion.prevhpos = prev_hpos; | 1677 | val_compute_motion.prevhpos = prev_hpos; |
| 1688 | /* We alalways handle all of them here; none of them remain to do. */ | 1678 | /* We always handle all of them here; none of them remain to do. */ |
| 1689 | val_compute_motion.ovstring_chars_done = 0; | 1679 | val_compute_motion.ovstring_chars_done = 0; |
| 1690 | 1680 | ||
| 1691 | /* Nonzero if have just continued a line */ | 1681 | /* Nonzero if have just continued a line */ |
| @@ -1986,9 +1976,11 @@ whether or not it is currently displayed in some window. */) | |||
| 1986 | struct text_pos pt; | 1976 | struct text_pos pt; |
| 1987 | struct window *w; | 1977 | struct window *w; |
| 1988 | Lisp_Object old_buffer; | 1978 | Lisp_Object old_buffer; |
| 1989 | struct gcpro gcpro1; | 1979 | EMACS_INT old_charpos IF_LINT (= 0), old_bytepos IF_LINT (= 0); |
| 1980 | struct gcpro gcpro1, gcpro2, gcpro3; | ||
| 1990 | Lisp_Object lcols = Qnil; | 1981 | Lisp_Object lcols = Qnil; |
| 1991 | double cols IF_LINT (= 0); | 1982 | double cols IF_LINT (= 0); |
| 1983 | void *itdata = NULL; | ||
| 1992 | 1984 | ||
| 1993 | /* Allow LINES to be of the form (HPOS . VPOS) aka (COLUMNS . LINES). */ | 1985 | /* Allow LINES to be of the form (HPOS . VPOS) aka (COLUMNS . LINES). */ |
| 1994 | if (CONSP (lines) && (NUMBERP (XCAR (lines)))) | 1986 | if (CONSP (lines) && (NUMBERP (XCAR (lines)))) |
| @@ -2006,12 +1998,16 @@ whether or not it is currently displayed in some window. */) | |||
| 2006 | w = XWINDOW (window); | 1998 | w = XWINDOW (window); |
| 2007 | 1999 | ||
| 2008 | old_buffer = Qnil; | 2000 | old_buffer = Qnil; |
| 2009 | GCPRO1 (old_buffer); | 2001 | GCPRO3 (old_buffer, old_charpos, old_bytepos); |
| 2010 | if (XBUFFER (w->buffer) != current_buffer) | 2002 | if (XBUFFER (w->buffer) != current_buffer) |
| 2011 | { | 2003 | { |
| 2012 | /* Set the window's buffer temporarily to the current buffer. */ | 2004 | /* Set the window's buffer temporarily to the current buffer. */ |
| 2013 | old_buffer = w->buffer; | 2005 | old_buffer = w->buffer; |
| 2006 | old_charpos = XMARKER (w->pointm)->charpos; | ||
| 2007 | old_bytepos = XMARKER (w->pointm)->bytepos; | ||
| 2014 | XSETBUFFER (w->buffer, current_buffer); | 2008 | XSETBUFFER (w->buffer, current_buffer); |
| 2009 | set_marker_both | ||
| 2010 | (w->pointm, w->buffer, BUF_PT (current_buffer), BUF_PT_BYTE (current_buffer)); | ||
| 2015 | } | 2011 | } |
| 2016 | 2012 | ||
| 2017 | if (noninteractive) | 2013 | if (noninteractive) |
| @@ -2023,30 +2019,33 @@ whether or not it is currently displayed in some window. */) | |||
| 2023 | else | 2019 | else |
| 2024 | { | 2020 | { |
| 2025 | EMACS_INT it_start; | 2021 | EMACS_INT it_start; |
| 2026 | int first_x, it_overshoot_expected IF_LINT (= 0); | 2022 | int first_x, it_overshoot_count = 0; |
| 2023 | int overshoot_handled = 0; | ||
| 2027 | 2024 | ||
| 2025 | itdata = bidi_shelve_cache (); | ||
| 2028 | SET_TEXT_POS (pt, PT, PT_BYTE); | 2026 | SET_TEXT_POS (pt, PT, PT_BYTE); |
| 2029 | start_display (&it, w, pt); | 2027 | start_display (&it, w, pt); |
| 2030 | first_x = it.first_visible_x; | 2028 | first_x = it.first_visible_x; |
| 2031 | it_start = IT_CHARPOS (it); | 2029 | it_start = IT_CHARPOS (it); |
| 2032 | 2030 | ||
| 2033 | /* See comments below for why we calculate this. */ | 2031 | /* See comments below for why we calculate this. */ |
| 2034 | if (XINT (lines) > 0) | 2032 | if (it.cmp_it.id >= 0) |
| 2033 | it_overshoot_count = 0; | ||
| 2034 | else if (it.method == GET_FROM_STRING) | ||
| 2035 | { | 2035 | { |
| 2036 | if (it.cmp_it.id >= 0) | 2036 | const char *s = SSDATA (it.string); |
| 2037 | it_overshoot_expected = 1; | 2037 | const char *e = s + SBYTES (it.string); |
| 2038 | else if (it.method == GET_FROM_STRING) | 2038 | while (s < e) |
| 2039 | { | 2039 | { |
| 2040 | const char *s = SSDATA (it.string); | 2040 | if (*s++ == '\n') |
| 2041 | const char *e = s + SBYTES (it.string); | 2041 | it_overshoot_count++; |
| 2042 | while (s < e && *s != '\n') | ||
| 2043 | ++s; | ||
| 2044 | it_overshoot_expected = (s == e) ? -1 : 0; | ||
| 2045 | } | 2042 | } |
| 2046 | else | 2043 | if (!it_overshoot_count) |
| 2047 | it_overshoot_expected = (it.method == GET_FROM_IMAGE | 2044 | it_overshoot_count = -1; |
| 2048 | || it.method == GET_FROM_STRETCH); | ||
| 2049 | } | 2045 | } |
| 2046 | else | ||
| 2047 | it_overshoot_count = | ||
| 2048 | !(it.method == GET_FROM_IMAGE || it.method == GET_FROM_STRETCH); | ||
| 2050 | 2049 | ||
| 2051 | /* Scan from the start of the line containing PT. If we don't | 2050 | /* Scan from the start of the line containing PT. If we don't |
| 2052 | do this, we start moving with IT->current_x == 0, while PT is | 2051 | do this, we start moving with IT->current_x == 0, while PT is |
| @@ -2060,55 +2059,58 @@ whether or not it is currently displayed in some window. */) | |||
| 2060 | tell, and it causes Bug#2694 . -- cyd */ | 2059 | tell, and it causes Bug#2694 . -- cyd */ |
| 2061 | move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); | 2060 | move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); |
| 2062 | 2061 | ||
| 2062 | /* IT may move too far if truncate-lines is on and PT lies | ||
| 2063 | beyond the right margin. IT may also move too far if the | ||
| 2064 | starting point is on a Lisp string that has embedded | ||
| 2065 | newlines. In these cases, backtrack. */ | ||
| 2066 | if (IT_CHARPOS (it) > it_start) | ||
| 2067 | { | ||
| 2068 | /* We need to backtrack also if the Lisp string contains no | ||
| 2069 | newlines, but there is a newline right after it. In this | ||
| 2070 | case, IT overshoots if there is an after-string just | ||
| 2071 | before the newline. */ | ||
| 2072 | if (it_overshoot_count < 0 | ||
| 2073 | && it.method == GET_FROM_BUFFER | ||
| 2074 | && it.c == '\n') | ||
| 2075 | it_overshoot_count = 1; | ||
| 2076 | if (it_overshoot_count > 0) | ||
| 2077 | move_it_by_lines (&it, -it_overshoot_count); | ||
| 2078 | |||
| 2079 | overshoot_handled = 1; | ||
| 2080 | } | ||
| 2063 | if (XINT (lines) <= 0) | 2081 | if (XINT (lines) <= 0) |
| 2064 | { | 2082 | { |
| 2065 | it.vpos = 0; | 2083 | it.vpos = 0; |
| 2066 | /* Do this even if LINES is 0, so that we move back to the | 2084 | /* Do this even if LINES is 0, so that we move back to the |
| 2067 | beginning of the current line as we ought. */ | 2085 | beginning of the current line as we ought. */ |
| 2068 | if (XINT (lines) == 0 || IT_CHARPOS (it) > 0) | 2086 | if (XINT (lines) == 0 || IT_CHARPOS (it) > 0) |
| 2069 | move_it_by_lines (&it, XINT (lines)); | 2087 | move_it_by_lines (&it, max (INT_MIN, XINT (lines))); |
| 2088 | } | ||
| 2089 | else if (overshoot_handled) | ||
| 2090 | { | ||
| 2091 | it.vpos = 0; | ||
| 2092 | move_it_by_lines (&it, min (INT_MAX, XINT (lines))); | ||
| 2070 | } | 2093 | } |
| 2071 | else | 2094 | else |
| 2072 | { | 2095 | { |
| 2073 | if (IT_CHARPOS (it) > it_start) | 2096 | /* Otherwise, we are at the first row occupied by PT, which |
| 2097 | might span multiple screen lines (e.g., if it's on a | ||
| 2098 | multi-line display string). We want to start from the | ||
| 2099 | last line that it occupies. */ | ||
| 2100 | if (it_start < ZV) | ||
| 2074 | { | 2101 | { |
| 2075 | /* IT may move too far if truncate-lines is on and PT | 2102 | while (IT_CHARPOS (it) <= it_start) |
| 2076 | lies beyond the right margin. In that case, | ||
| 2077 | backtrack unless the starting point is on an image, | ||
| 2078 | stretch glyph, composition, or Lisp string. */ | ||
| 2079 | if (!it_overshoot_expected | ||
| 2080 | /* Also, backtrack if the Lisp string contains no | ||
| 2081 | newline, but there is a newline right after it. | ||
| 2082 | In this case, IT overshoots if there is an | ||
| 2083 | after-string just before the newline. */ | ||
| 2084 | || (it_overshoot_expected < 0 | ||
| 2085 | && it.method == GET_FROM_BUFFER | ||
| 2086 | && it.c == '\n')) | ||
| 2087 | move_it_by_lines (&it, -1); | ||
| 2088 | it.vpos = 0; | ||
| 2089 | move_it_by_lines (&it, XINT (lines)); | ||
| 2090 | } | ||
| 2091 | else | ||
| 2092 | { | ||
| 2093 | /* Otherwise, we are at the first row occupied by PT, | ||
| 2094 | which might span multiple screen lines (e.g., if it's | ||
| 2095 | on a multi-line display string). We want to start | ||
| 2096 | from the last line that it occupies. */ | ||
| 2097 | if (it_start < ZV) | ||
| 2098 | { | ||
| 2099 | while (IT_CHARPOS (it) <= it_start) | ||
| 2100 | { | ||
| 2101 | it.vpos = 0; | ||
| 2102 | move_it_by_lines (&it, 1); | ||
| 2103 | } | ||
| 2104 | if (XINT (lines) > 1) | ||
| 2105 | move_it_by_lines (&it, XINT (lines) - 1); | ||
| 2106 | } | ||
| 2107 | else | ||
| 2108 | { | 2103 | { |
| 2109 | it.vpos = 0; | 2104 | it.vpos = 0; |
| 2110 | move_it_by_lines (&it, XINT (lines)); | 2105 | move_it_by_lines (&it, 1); |
| 2111 | } | 2106 | } |
| 2107 | if (XINT (lines) > 1) | ||
| 2108 | move_it_by_lines (&it, min (INT_MAX, XINT (lines) - 1)); | ||
| 2109 | } | ||
| 2110 | else | ||
| 2111 | { | ||
| 2112 | it.vpos = 0; | ||
| 2113 | move_it_by_lines (&it, min (INT_MAX, XINT (lines))); | ||
| 2112 | } | 2114 | } |
| 2113 | } | 2115 | } |
| 2114 | 2116 | ||
| @@ -2129,10 +2131,14 @@ whether or not it is currently displayed in some window. */) | |||
| 2129 | } | 2131 | } |
| 2130 | 2132 | ||
| 2131 | SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); | 2133 | SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); |
| 2134 | bidi_unshelve_cache (itdata, 0); | ||
| 2132 | } | 2135 | } |
| 2133 | 2136 | ||
| 2134 | if (BUFFERP (old_buffer)) | 2137 | if (BUFFERP (old_buffer)) |
| 2135 | w->buffer = old_buffer; | 2138 | { |
| 2139 | w->buffer = old_buffer; | ||
| 2140 | set_marker_both (w->pointm, w->buffer, old_charpos, old_bytepos); | ||
| 2141 | } | ||
| 2136 | 2142 | ||
| 2137 | RETURN_UNGCPRO (make_number (it.vpos)); | 2143 | RETURN_UNGCPRO (make_number (it.vpos)); |
| 2138 | } | 2144 | } |