From: Eli Zaretskii Date: Sat, 28 May 2011 17:23:44 +0000 (+0300) Subject: Fix cursor motion across display strings covering reordered text. X-Git-Tag: emacs-pretest-24.0.90~104^2~275^2~36 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=0e14fe90d816f77788f1985ce853b473b9416d3b;p=emacs.git Fix cursor motion across display strings covering reordered text. src/xdisp.c (set_cursor_from_row): Set start and stop points according to the row's direction when priming the loop that looks for the glyph on which to display cursor. (single_display_spec_intangible_p): Function deleted. (display_prop_intangible_p): Reimplement to call handle_display_spec instead of single_display_spec_intangible_p. Accept 3 additional arguments needed by handle_display_spec. This fixes incorrect cursor motion across display property with complex values: lists, `(when COND...)' forms, etc. (single_display_spec_string_p): Support property values that are lists with the argument STRING its top-level element. (display_prop_string_p): Fix the condition for processing a property that is a list to be consistent with handle_display_spec. src/keyboard.c (adjust_point_for_property): Adjust the call to display_prop_intangible_p to its new signature. src/dispextern.h (display_prop_intangible_p): Adjust prototype. --- diff --git a/src/ChangeLog b/src/ChangeLog index b651856f276..12c0bde290b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,8 +1,23 @@ 2011-05-28 Eli Zaretskii - * xdisp.c (set_cursor_from_row): Set start and stop points of the - loop that looks for the glyph on which to display cursor according - to the row's direction. + * xdisp.c (set_cursor_from_row): Set start and stop points + according to the row's direction when priming the loop that looks + for the glyph on which to display cursor. + (single_display_spec_intangible_p): Function deleted. + (display_prop_intangible_p): Reimplement to call + handle_display_spec instead of single_display_spec_intangible_p. + Accept 3 additional arguments needed by handle_display_spec. This + fixes incorrect cursor motion across display property with complex + values: lists, `(when COND...)' forms, etc. + (single_display_spec_string_p): Support property values that are + lists with the argument STRING its top-level element. + (display_prop_string_p): Fix the condition for processing a + property that is a list to be consistent with handle_display_spec. + + * keyboard.c (adjust_point_for_property): Adjust the call to + display_prop_intangible_p to its new signature. + + * dispextern.h (display_prop_intangible_p): Adjust prototype. 2011-05-21 Eli Zaretskii diff --git a/src/dispextern.h b/src/dispextern.h index 6c09f21a78f..7138c2225e8 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -2957,7 +2957,7 @@ struct glyph_row *row_containing_pos (struct window *, EMACS_INT, struct glyph_row *, struct glyph_row *, int); int line_bottom_y (struct it *); -int display_prop_intangible_p (Lisp_Object); +int display_prop_intangible_p (Lisp_Object, Lisp_Object, EMACS_INT, EMACS_INT); void resize_echo_area_exactly (void); int resize_mini_window (struct window *, int); #if defined USE_TOOLKIT_SCROLL_BARS && !defined USE_GTK diff --git a/src/keyboard.c b/src/keyboard.c index a94456fce2e..ad4fd079049 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1729,7 +1729,7 @@ adjust_point_for_property (EMACS_INT last_pt, int modified) && PT > BEGV && PT < ZV && !NILP (val = get_char_property_and_overlay (make_number (PT), Qdisplay, Qnil, &overlay)) - && display_prop_intangible_p (val) + && display_prop_intangible_p (val, overlay, PT, PT_BYTE) && (!OVERLAYP (overlay) ? get_property_and_range (PT, Qdisplay, &val, &beg, &end, Qnil) : (beg = OVERLAY_POSITION (OVERLAY_START (overlay)), diff --git a/src/xdisp.c b/src/xdisp.c index 9d5ec9f1f60..714c18be466 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -4375,83 +4375,31 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, return 0; } - -/* Check if SPEC is a display sub-property value whose text should be - treated as intangible. */ - -static int -single_display_spec_intangible_p (Lisp_Object prop) -{ - /* Skip over `when FORM'. */ - if (CONSP (prop) && EQ (XCAR (prop), Qwhen)) - { - prop = XCDR (prop); - if (!CONSP (prop)) - return 0; - prop = XCDR (prop); - } - - if (STRINGP (prop)) - return 1; - - if (!CONSP (prop)) - return 0; - - /* Skip over `margin LOCATION'. If LOCATION is in the margins, - we don't need to treat text as intangible. */ - if (EQ (XCAR (prop), Qmargin)) - { - prop = XCDR (prop); - if (!CONSP (prop)) - return 0; - - prop = XCDR (prop); - if (!CONSP (prop) - || EQ (XCAR (prop), Qleft_margin) - || EQ (XCAR (prop), Qright_margin)) - return 0; - } - - return (CONSP (prop) - && (EQ (XCAR (prop), Qimage) - || EQ (XCAR (prop), Qspace))); -} - - /* Check if PROP is a display property value whose text should be - treated as intangible. */ + treated as intangible. OVERLAY is the overlay from which PROP + came, or nil if it came from a text property. CHARPOS and BYTEPOS + specify the buffer position covered by PROP. */ int -display_prop_intangible_p (Lisp_Object prop) +display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay, + EMACS_INT charpos, EMACS_INT bytepos) { - if (CONSP (prop) - && CONSP (XCAR (prop)) - && !EQ (Qmargin, XCAR (XCAR (prop)))) - { - /* A list of sub-properties. */ - while (CONSP (prop)) - { - if (single_display_spec_intangible_p (XCAR (prop))) - return 1; - prop = XCDR (prop); - } - } - else if (VECTORP (prop)) - { - /* A vector of sub-properties. */ - int i; - for (i = 0; i < ASIZE (prop); ++i) - if (single_display_spec_intangible_p (AREF (prop, i))) - return 1; - } - else - return single_display_spec_intangible_p (prop); + int frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame)); + struct text_pos position; - return 0; + SET_TEXT_POS (position, charpos, bytepos); + return handle_display_spec (NULL, prop, Qnil, overlay, + &position, charpos, frame_window_p); } -/* Return 1 if PROP is a display sub-property value containing STRING. */ +/* Return 1 if PROP is a display sub-property value containing STRING. + + Implementation note: this and the following function are really + special cases of handle_display_spec and + handle_single_display_spec, and should ideally use the same code. + Until they do, these two pairs must be consistent and must be + modified in sync. */ static int single_display_spec_string_p (Lisp_Object prop, Lisp_Object string) @@ -4465,6 +4413,9 @@ single_display_spec_string_p (Lisp_Object prop, Lisp_Object string) prop = XCDR (prop); if (!CONSP (prop)) return 0; + /* FIXME: We should eval the condition following `when', like + handle_single_display_spec does, and retrun zero if it + evaluates to nil. */ prop = XCDR (prop); } @@ -4481,7 +4432,7 @@ single_display_spec_string_p (Lisp_Object prop, Lisp_Object string) return 0; } - return CONSP (prop) && EQ (XCAR (prop), string); + return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string)); } @@ -4491,8 +4442,8 @@ static int display_prop_string_p (Lisp_Object prop, Lisp_Object string) { if (CONSP (prop) - && CONSP (XCAR (prop)) - && !EQ (Qmargin, XCAR (XCAR (prop)))) + && !EQ (XCAR (prop), Qwhen) + && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop))))) { /* A list of sub-properties. */ while (CONSP (prop))