aboutsummaryrefslogtreecommitdiffstats
path: root/src/indent.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/indent.c')
-rw-r--r--src/indent.c160
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
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
@@ -56,7 +56,7 @@ EMACS_INT last_known_column_point;
56static int last_known_column_modified; 56static int last_known_column_modified;
57 57
58static EMACS_INT current_column_1 (void); 58static EMACS_INT current_column_1 (void);
59static EMACS_INT position_indentation (int); 59static 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
323static int
324sane_tab_width (void)
325{
326 EMACS_INT n = XFASTINT (BVAR (current_buffer, tab_width));
327 return 0 < n && n <= 1000 ? n : 8;
328}
329
330EMACS_INT 321EMACS_INT
331current_column (void) 322current_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)
515static void 506static void
516scan_for_column (EMACS_INT *endpos, EMACS_INT *goalcol, EMACS_INT *prevcol) 507scan_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
727static double 718static double
728string_display_width (string, beg, end) 719string_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
867static EMACS_INT 857static EMACS_INT
868position_indentation (register int pos_byte) 858position_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}