X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/fd15a4daca3b32487b751006a5e7be7732fdf9ea..351c9889873cb0e8c4e43bc51f9a5b36b81ac9a6:/src/indent.c?ds=sidebyside diff --git a/src/indent.c b/src/indent.c index ffde428c12..d6709d56ee 100644 --- a/src/indent.c +++ b/src/indent.c @@ -1,6 +1,6 @@ /* Indentation functions. - Copyright (C) 1985,86,87,88,93,94,95,98,2000,01,02,03,2004 - Free Software Foundation, Inc. + Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1998, 2000, 2001, + 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -67,6 +67,8 @@ static double position_indentation P_ ((int)); int current_column_bol_cache; +extern Lisp_Object Qfontification_functions; + /* Get the display table to use for the current buffer. */ struct Lisp_Char_Table * @@ -222,7 +224,7 @@ skip_invisible (pos, next_boundary_p, to, window) Lisp_Object window; { Lisp_Object prop, position, overlay_limit, proplimit; - Lisp_Object buffer; + Lisp_Object buffer, tmp; int end, inv_p; XSETFASTINT (position, pos); @@ -253,8 +255,9 @@ 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 = XFASTINT (Fnext_single_property_change (position, Qinvisible, - buffer, proplimit)); + tmp = Fnext_single_property_change (position, Qinvisible, + buffer, proplimit); + end = XFASTINT (tmp); #if 0 /* Don't put the boundary in the middle of multibyte form if there is no actual property change. */ @@ -341,7 +344,9 @@ will have a variable width) Ignores finite width of frame, which means that this function may return values greater than (frame-width). Whether the line is visible (if `selective-display' is t) has no effect; -however, ^M is treated as end of line when `selective-display' is t. */) +however, ^M is treated as end of line when `selective-display' is t. +Text that has an invisible property is considered as having width 0, unless +`buffer-invisibility-spec' specifies that it is replaced by an ellipsis. */) () { Lisp_Object temp; @@ -1885,7 +1890,7 @@ vmotion (from, vtarget, w) struct position pos; /* vpos is cumulative vertical position, changed as from is changed */ register int vpos = 0; - Lisp_Object prevline; + int prevline; register int first; int from_byte; int lmargin = hscroll > 0 ? 1 - hscroll : 0; @@ -1919,23 +1924,21 @@ vmotion (from, vtarget, w) { Lisp_Object propval; - XSETFASTINT (prevline, find_next_newline_no_quit (from - 1, -1)); - while (XFASTINT (prevline) > BEGV + prevline = find_next_newline_no_quit (from - 1, -1); + while (prevline > BEGV && ((selective > 0 - && indented_beyond_p (XFASTINT (prevline), - CHAR_TO_BYTE (XFASTINT (prevline)), + && indented_beyond_p (prevline, + CHAR_TO_BYTE (prevline), (double) selective)) /* iftc */ - /* watch out for newlines with `invisible' property */ - || (propval = Fget_char_property (prevline, + /* Watch out for newlines with `invisible' property. + When moving upward, check the newline before. */ + || (propval = Fget_char_property (make_number (prevline - 1), Qinvisible, text_prop_object), TEXT_PROP_MEANS_INVISIBLE (propval)))) - XSETFASTINT (prevline, - find_next_newline_no_quit (XFASTINT (prevline) - 1, - -1)); - pos = *compute_motion (XFASTINT (prevline), 0, - lmargin + (XFASTINT (prevline) == BEG - ? start_hpos : 0), + prevline = find_next_newline_no_quit (prevline - 1, -1); + pos = *compute_motion (prevline, 0, + lmargin + (prevline == BEG ? start_hpos : 0), 0, from, /* Don't care for VPOS... */ @@ -1946,12 +1949,11 @@ vmotion (from, vtarget, w) /* This compensates for start_hpos so that a tab as first character still occupies 8 columns. */ - (XFASTINT (prevline) == BEG - ? -start_hpos : 0), + (prevline == BEG ? -start_hpos : 0), w); vpos -= pos.vpos; first = 0; - from = XFASTINT (prevline); + from = prevline; } /* If we made exactly the desired vertical distance, @@ -1979,21 +1981,21 @@ vmotion (from, vtarget, w) { Lisp_Object propval; - XSETFASTINT (prevline, find_next_newline_no_quit (from, -1)); - while (XFASTINT (prevline) > BEGV + prevline = find_next_newline_no_quit (from, -1); + while (prevline > BEGV && ((selective > 0 - && indented_beyond_p (XFASTINT (prevline), - CHAR_TO_BYTE (XFASTINT (prevline)), + && indented_beyond_p (prevline, + CHAR_TO_BYTE (prevline), (double) selective)) /* iftc */ - /* watch out for newlines with `invisible' property */ - || (propval = Fget_char_property (prevline, Qinvisible, + /* Watch out for newlines with `invisible' property. + When moving downward, check the newline after. */ + || (propval = Fget_char_property (make_number (prevline), + Qinvisible, text_prop_object), TEXT_PROP_MEANS_INVISIBLE (propval)))) - XSETFASTINT (prevline, - find_next_newline_no_quit (XFASTINT (prevline) - 1, - -1)); - pos = *compute_motion (XFASTINT (prevline), 0, - lmargin + (XFASTINT (prevline) == BEG + prevline = find_next_newline_no_quit (prevline - 1, -1); + pos = *compute_motion (prevline, 0, + lmargin + (prevline == BEG ? start_hpos : 0), 0, from, @@ -2002,7 +2004,7 @@ vmotion (from, vtarget, w) /* ... nor HPOS. */ 1 << (BITS_PER_SHORT - 1), -1, hscroll, - (XFASTINT (prevline) == BEG ? -start_hpos : 0), + (prevline == BEG ? -start_hpos : 0), w); did_motion = 1; } @@ -2049,6 +2051,7 @@ whether or not it is currently displayed in some window. */) struct window *w; Lisp_Object old_buffer; struct gcpro gcpro1; + int count = SPECPDL_INDEX (); CHECK_NUMBER (lines); if (! NILP (window)) @@ -2066,25 +2069,55 @@ whether or not it is currently displayed in some window. */) XSETBUFFER (w->buffer, current_buffer); } - SET_TEXT_POS (pt, PT, PT_BYTE); - start_display (&it, w, pt); - - /* 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); + /* Don't fontify text that we just move across. */ + specbind (Qfontification_functions, Qnil); - if (XINT (lines) != 0) - move_it_by_lines (&it, XINT (lines), 0); - - SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); + if (noninteractive) + { + struct position pos; + pos = *vmotion (PT, XINT (lines), w); + SET_PT_BOTH (pos.bufpos, pos.bytepos); + } + else + { + int it_start; + int oselective; + + SET_TEXT_POS (pt, PT, PT_BYTE); + start_display (&it, w, pt); + + /* Scan from the start of the 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. */ + it_start = IT_CHARPOS (it); + reseat_at_previous_visible_line_start (&it); + it.current_x = it.hpos = 0; + /* Temporarily disable selective display so we don't move too far */ + oselective = it.selective; + it.selective = 0; + move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); + it.selective = oselective; + + /* Move back if we got too far. This may happen if + truncate-lines is on and PT is beyond right margin. */ + if (IT_CHARPOS (it) > it_start && XINT (lines) > 0) + move_it_by_lines (&it, -1, 0); + + it.vpos = 0; + /* Do this even if LINES is 0, so that we move back + to the beginning of the current line as we ought. */ + 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; + unbind_to (count, Qnil); RETURN_UNGCPRO (make_number (it.vpos)); }