X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/d6e483a4dac328f388baec4bd1e795a921907230..f4e1400d40a45059b6cc54b67787da1792630e02:/src/indent.c diff --git a/src/indent.c b/src/indent.c index 2a62ab6fed..22039ebca6 100644 --- a/src/indent.c +++ b/src/indent.c @@ -1,5 +1,5 @@ /* Indentation functions. - Copyright (C) 1985,86,87,88,93,94,95,98, 2000, 2001 + Copyright (C) 1985,86,87,88,93,94,95,98, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -47,7 +47,7 @@ int indent_tabs_mode; Some things in set last_known_column_point to -1 to mark the memorized value as invalid. */ -int last_known_column; +double last_known_column; /* Value of point when current_column was called. */ @@ -57,8 +57,8 @@ int last_known_column_point; int last_known_column_modified; -static int current_column_1 P_ ((void)); -static int position_indentation P_ ((int)); +static double current_column_1 P_ ((void)); +static double position_indentation P_ ((int)); /* Cache of beginning of line found by the last call of current_column. */ @@ -221,7 +221,7 @@ skip_invisible (pos, next_boundary_p, to, window) { Lisp_Object prop, position, overlay_limit, proplimit; Lisp_Object buffer; - int end; + int end, inv_p; XSETFASTINT (position, pos); XSETBUFFER (buffer, current_buffer); @@ -266,11 +266,13 @@ skip_invisible (pos, next_boundary_p, to, window) } /* if the `invisible' property is set, we can skip to the next property change */ - if (!NILP (window) && EQ (XWINDOW (window)->buffer, buffer)) - prop = Fget_char_property (position, Qinvisible, window); - else - prop = Fget_char_property (position, Qinvisible, buffer); - if (TEXT_PROP_MEANS_INVISIBLE (prop) > NILP (window)) + prop = Fget_char_property (position, Qinvisible, + (!NILP (window) + && EQ (XWINDOW (window)->buffer, buffer)) + ? window : buffer); + inv_p = TEXT_PROP_MEANS_INVISIBLE (prop); + /* When counting columns (window == nil), don't skip over ellipsis text. */ + if (NILP (window) ? inv_p == 1 : inv_p) return *next_boundary_p; return pos; } @@ -327,6 +329,7 @@ check_composition (pos, pos_byte, point, len, len_byte, width) } \ } while (0) + 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 @@ -340,7 +343,7 @@ however, ^M is treated as end of line when `selective-display' is t. */) () { Lisp_Object temp; - XSETFASTINT (temp, current_column ()); + XSETFASTINT (temp, (int) current_column ()); /* iftc */ return temp; } @@ -352,7 +355,7 @@ invalidate_current_column () last_known_column_point = 0; } -int +double current_column () { register int col; @@ -399,25 +402,25 @@ current_column () { EMACS_INT i, n; Lisp_Object charvec; - + if (ptr == stop) { /* We stopped either for the beginning of the buffer or for the gap. */ if (ptr == BEGV_ADDR) break; - + /* It was the gap. Jump back over it. */ stop = BEGV_ADDR; ptr = GPT_ADDR; - + /* Check whether that brings us to beginning of buffer. */ if (BEGV >= GPT) break; } c = *--ptr; - + if (dp && VECTORP (DISP_CHAR_VECTOR (dp, c))) { charvec = DISP_CHAR_VECTOR (dp, c); @@ -428,7 +431,7 @@ current_column () charvec = Qnil; n = 1; } - + for (i = n - 1; i >= 0; --i) { if (VECTORP (charvec)) @@ -436,14 +439,14 @@ current_column () /* This should be handled the same as next_element_from_display_vector does it. */ Lisp_Object entry = AREF (charvec, i); - + if (INTEGERP (entry) && GLYPH_CHAR_VALID_P (XFASTINT (entry))) c = FAST_GLYPH_CHAR (XFASTINT (entry)); else c = ' '; } - + if (c >= 040 && c < 0177) col++; else if (c == '\n' @@ -457,7 +460,7 @@ current_column () { if (tab_seen) col = ((col + tab_width) / tab_width) * tab_width; - + post_tab += col; col = 0; tab_seen = 1; @@ -499,7 +502,7 @@ current_column () This function handles characters that are invisible due to text properties or overlays. */ -static int +static double current_column_1 () { register int tab_width = XINT (current_buffer->tab_width); @@ -510,7 +513,7 @@ current_column_1 () /* Start the scan at the beginning of this line with column number 0. */ register int col = 0; int scan, scan_byte; - int next_boundary, next_boundary_byte; + int next_boundary; int opoint = PT, opoint_byte = PT_BYTE; scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1); @@ -518,7 +521,6 @@ current_column_1 () scan = PT, scan_byte = PT_BYTE; SET_PT_BOTH (opoint, opoint_byte); next_boundary = scan; - next_boundary_byte = scan_byte; if (tab_width <= 0 || tab_width > 1000) tab_width = 8; @@ -538,7 +540,6 @@ current_column_1 () goto endloop; if (scan != old_scan) scan_byte = CHAR_TO_BYTE (scan); - next_boundary_byte = CHAR_TO_BYTE (next_boundary); } /* Check composition sequence. */ @@ -590,7 +591,6 @@ current_column_1 () goto endloop; if (c == '\t') { - int prev_col = col; col += tab_width; col = col / tab_width * tab_width; } @@ -609,7 +609,6 @@ current_column_1 () goto endloop; if (c == '\t') { - int prev_col = col; col += tab_width; col = col / tab_width * tab_width; } @@ -617,11 +616,13 @@ current_column_1 () { unsigned char *ptr; int bytes, width, wide_column; - - scan_byte--; + ptr = BYTE_POS_ADDR (scan_byte); MULTIBYTE_BYTES_WIDTH (ptr, dp); scan_byte += bytes; + /* Subtract one to compensate for the increment + that is going to happen below. */ + scan_byte--; col += width; } else if (ctl_arrow && (c < 040 || c == 0177)) @@ -651,7 +652,7 @@ current_column_1 () If BEG is nil, that stands for the beginning of STRING. If END is nil, that stands for the end of STRING. */ -static int +static double string_display_width (string, beg, end) Lisp_Object string, beg, end; { @@ -666,7 +667,7 @@ string_display_width (string, beg, end) int b, e; if (NILP (end)) - e = XSTRING (string)->size; + e = SCHARS (string); else { CHECK_NUMBER (end); @@ -682,10 +683,10 @@ string_display_width (string, beg, end) } /* Make a pointer for decrementing through the chars before point. */ - ptr = XSTRING (string)->data + e; + ptr = SDATA (string) + e; /* Make a pointer to where consecutive chars leave off, going backwards from point. */ - stop = XSTRING (string)->data + b; + stop = SDATA (string) + b; if (tab_width <= 0 || tab_width > 1000) tab_width = 8; @@ -777,7 +778,7 @@ even if that goes past COLUMN; by default, MININUM is zero. */) } -static int position_indentation P_ ((int)); +static double position_indentation P_ ((int)); DEFUN ("current-indentation", Fcurrent_indentation, Scurrent_indentation, 0, 0, 0, @@ -791,12 +792,12 @@ following any initial whitespace. */) scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, 1); - XSETFASTINT (val, position_indentation (PT_BYTE)); + XSETFASTINT (val, (int) position_indentation (PT_BYTE)); /* iftc */ SET_PT_BOTH (opoint, opoint_byte); return val; } -static int +static double position_indentation (pos_byte) register int pos_byte; { @@ -846,7 +847,7 @@ position_indentation (pos_byte) /* The -1 and +1 arrange to point at the first byte of gap (if STOP_POS_BYTE is the position of the gap) rather than at the data after the gap. */ - + stop = BYTE_POS_ADDR (stop_pos_byte - 1) + 1; p = BYTE_POS_ADDR (pos_byte); } @@ -888,9 +889,10 @@ position_indentation (pos_byte) int indented_beyond_p (pos, pos_byte, column) - int pos, pos_byte, column; + int pos, pos_byte; + double column; { - int val; + double val; int opoint = PT, opoint_byte = PT_BYTE; SET_PT_BOTH (pos, pos_byte); @@ -899,7 +901,7 @@ indented_beyond_p (pos, pos_byte, column) val = position_indentation (PT_BYTE); SET_PT_BOTH (opoint, opoint_byte); - return val >= column; + return val >= column; /* hmm, float comparison */ } DEFUN ("move-to-column", Fmove_to_column, Smove_to_column, 1, 2, "p", @@ -934,9 +936,7 @@ The return value is the current column. */) Lisp_Object val; int prev_col = 0; int c = 0; - int next_boundary; - - int pos_byte, end_byte, next_boundary_byte; + int next_boundary, pos_byte; if (tab_width <= 0 || tab_width > 1000) tab_width = 8; CHECK_NATNUM (column); @@ -945,9 +945,7 @@ The return value is the current column. */) pos = PT; pos_byte = PT_BYTE; end = ZV; - end_byte = ZV_BYTE; next_boundary = pos; - next_boundary_byte = PT_BYTE; /* If we're starting past the desired column, back up to beginning of line and scan from there. */ @@ -967,7 +965,6 @@ The return value is the current column. */) pos = skip_invisible (pos, &next_boundary, end, Qnil); if (pos != prev) pos_byte = CHAR_TO_BYTE (pos); - next_boundary_byte = CHAR_TO_BYTE (next_boundary); if (pos >= end) goto endloop; } @@ -1098,7 +1095,7 @@ The return value is the current column. */) goal_pt_byte = PT_BYTE; Findent_to (make_number (col), Qnil); SET_PT_BOTH (goal_pt, goal_pt_byte); - + /* Set the last_known... vars consistently. */ col = goal; } @@ -1262,7 +1259,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width, int newpos; /* Don't skip invisible if we are already at the margin. */ - if (vpos > tovpos || vpos == tovpos && hpos >= tohpos) + if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos)) { if (contin_hpos && prev_hpos == 0 && hpos > tohpos @@ -1357,7 +1354,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width, W_ ^---- next after the point ^---- next char. after the point. ---------- - In case of wide-column character + In case of wide-column character The problem here is continuation at a wide-column character. In this case, the line may shorter less than WIDTH. @@ -1444,7 +1441,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width, break; } - if (vpos > tovpos || vpos == tovpos && hpos >= tohpos) + if (vpos > tovpos || (vpos == tovpos && hpos >= tohpos)) { if (contin_hpos && prev_hpos == 0 && hpos > tohpos @@ -1527,7 +1524,7 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width, { EMACS_INT i, n; Lisp_Object charvec; - + c = FETCH_BYTE (pos_byte); /* Check composition sequence. */ @@ -1593,14 +1590,14 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width, /* This should be handled the same as next_element_from_display_vector does it. */ Lisp_Object entry = AREF (charvec, i); - + if (INTEGERP (entry) && GLYPH_CHAR_VALID_P (XFASTINT (entry))) c = FAST_GLYPH_CHAR (XFASTINT (entry)); else c = ' '; } - + if (c >= 040 && c < 0177) hpos++; else if (c == '\t') @@ -1614,7 +1611,8 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width, else if (c == '\n') { if (selective > 0 - && indented_beyond_p (pos, pos_byte, selective)) + && indented_beyond_p (pos, pos_byte, + (double) selective)) /* iftc */ { /* If (pos == to), we don't have to take care of selective display. */ @@ -1629,7 +1627,8 @@ compute_motion (from, fromvpos, fromhpos, did_motion, to, tovpos, tohpos, width, pos_byte = CHAR_TO_BYTE (pos); } while (pos < to - && indented_beyond_p (pos, pos_byte, selective)); + && indented_beyond_p (pos, pos_byte, + (double) selective)); /* iftc */ /* Allow for the " ..." that is displayed for them. */ if (selective_rlen) { @@ -1879,7 +1878,7 @@ vmotion (from, vtarget, w) && ((selective > 0 && indented_beyond_p (XFASTINT (prevline), CHAR_TO_BYTE (XFASTINT (prevline)), - selective)) + (double) selective)) /* iftc */ /* watch out for newlines with `invisible' property */ || (propval = Fget_char_property (prevline, Qinvisible, @@ -1892,7 +1891,7 @@ vmotion (from, vtarget, w) lmargin + (XFASTINT (prevline) == BEG ? start_hpos : 0), 0, - from, + from, /* Don't care for VPOS... */ 1 << (BITS_PER_SHORT - 1), /* ... nor HPOS. */ @@ -1939,7 +1938,7 @@ vmotion (from, vtarget, w) && ((selective > 0 && indented_beyond_p (XFASTINT (prevline), CHAR_TO_BYTE (XFASTINT (prevline)), - selective)) + (double) selective)) /* iftc */ /* watch out for newlines with `invisible' property */ || (propval = Fget_char_property (prevline, Qinvisible, text_prop_object), @@ -1951,7 +1950,7 @@ vmotion (from, vtarget, w) lmargin + (XFASTINT (prevline) == BEG ? start_hpos : 0), 0, - from, + from, /* Don't care for VPOS... */ 1 << (BITS_PER_SHORT - 1), /* ... nor HPOS. */ @@ -2020,15 +2019,26 @@ whether or not it is currently displayed in some window. */) old_buffer = w->buffer; XSETBUFFER (w->buffer, current_buffer); } - + SET_TEXT_POS (pt, PT, PT_BYTE); start_display (&it, w, pt); - move_it_by_lines (&it, XINT (lines), 0); + + /* Move to the start of the display line containing PT. If we don't + do this, we start moving with IT->current_x == 0, while PT is + really at some x > 0. The effect is, in continuation lines, that + we end up with the iterator placed at where it thinks X is 0, + while the end position is really at some X > 0, the same X that + PT had. */ + move_it_by_lines (&it, 0, 0); + + if (XINT (lines) != 0) + move_it_by_lines (&it, XINT (lines), 0); + SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); if (BUFFERP (old_buffer)) w->buffer = old_buffer; - + RETURN_UNGCPRO (make_number (it.vpos)); }