[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: address@hidden: vertical-motion]
From: |
Chong Yidong |
Subject: |
Re: address@hidden: vertical-motion] |
Date: |
Mon, 28 Aug 2006 18:00:43 -0400 |
User-agent: |
Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux) |
> From: KOBAYASHI Yasuhiro <address@hidden>
> Subject: vertical-motion
>
> It seems that vertical-motion is not right in the case which
> some propertized texts are included in the line.
>
> (defun test-case (n)
> ;; Preparate the test buffer.
> (switch-to-buffer (get-buffer-create "test"))
> (erase-buffer)
> (let ((pos (point-min)))
> (dotimes (i 3) (insert "\t\t\t\t\t\n"))
> (while (< pos (point-max))
> (and (= (char-after pos) ?\t)
> (put-text-property pos (1+ pos) 'display (propertize " >")))
> (setq pos (1+ pos))))
> ;; The following is the test case.
> (goto-char (point-min))
> (while (< (point) (point-max))
> (beginning-of-line)
> (forward-char n)
> ;; If POINT is not on the edge of the line,
> ;; POINT move to the beginning of the save line.
> (vertical-motion 1)))
>
> - - Strange actions.
> (test-case 1)
The problem is that when the iterator method at PT is GET_FROM_STRING,
the value of it.current after calling move_it_to is PT + 1. This is
because the call to set_iterator_to_next in xdisp.c:6607 (inside
move_it_in_display_line_to), upon reaching the end of the display
string at PT, sees that there are no more strings to display at PT and
calls pop_it, which automagically advances the iterator to PT + 1.
The code in Fvertical_motion then misfires:
/* Move back if we got too far. This may happen if
truncate-lines is on and PT is beyond right margin.
It may also happen if it_start is on an image or a stretch
glyph -- in that case, don't go back. */
if (IT_CHARPOS (it) > it_start && XINT (lines) > 0
&& !start_on_image_or_stretch_p)
move_it_by_lines (&it, -1, 0);
I propose the following fix. It fixes the bug described in the above
bug report.
*** emacs/src/indent.c.~1.183.~ 2006-02-25 13:07:18.000000000 -0500
--- emacs/src/indent.c 2006-08-28 17:54:41.000000000 -0400
***************
*** 2074,2080 ****
{
int it_start;
int oselective;
! int start_on_image_or_stretch_p;
SET_TEXT_POS (pt, PT, PT_BYTE);
start_display (&it, w, pt);
--- 2074,2080 ----
{
int it_start;
int oselective;
! int start_on_image_or_stretch_or_string_p;
SET_TEXT_POS (pt, PT, PT_BYTE);
start_display (&it, w, pt);
***************
*** 2086,2093 ****
while the end position is really at some X > 0, the same X that
PT had. */
it_start = IT_CHARPOS (it);
! start_on_image_or_stretch_p = (it.method == GET_FROM_IMAGE
! || it.method == GET_FROM_STRETCH);
reseat_at_previous_visible_line_start (&it);
it.current_x = it.hpos = 0;
/* Temporarily disable selective display so we don't move too far */
--- 2086,2094 ----
while the end position is really at some X > 0, the same X that
PT had. */
it_start = IT_CHARPOS (it);
! start_on_image_or_stretch_or_string_p = (it.method == GET_FROM_IMAGE
! || it.method == GET_FROM_STRETCH
! || it.method == GET_FROM_STRING);
reseat_at_previous_visible_line_start (&it);
it.current_x = it.hpos = 0;
/* Temporarily disable selective display so we don't move too far */
***************
*** 2098,2107 ****
/* Move back if we got too far. This may happen if
truncate-lines is on and PT is beyond right margin.
! It may also happen if it_start is on an image or a stretch
! glyph -- in that case, don't go back. */
if (IT_CHARPOS (it) > it_start && XINT (lines) > 0
! && !start_on_image_or_stretch_p)
move_it_by_lines (&it, -1, 0);
it.vpos = 0;
--- 2099,2108 ----
/* Move back if we got too far. This may happen if
truncate-lines is on and PT is beyond right margin.
! It may also happen if it_start is on an image, stretch
! glyph, or string -- in that case, don't go back. */
if (IT_CHARPOS (it) > it_start && XINT (lines) > 0
! && !start_on_image_or_stretch_or_string_p)
move_it_by_lines (&it, -1, 0);
it.vpos = 0;