From: Jimmy Aguilar Mena Date: Sat, 12 Oct 2019 16:10:48 +0000 (+0200) Subject: New parameter to control the face extension.. X-Git-Tag: emacs-27.0.90~1077^2~16 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=e02fe26c7fcccb4059a7c7baba20bd9cb3b9a313;p=emacs.git New parameter to control the face extension.. * src/xdisp.c (handle_face_prop_general): New function to specialize handle_face_prop with ATTR_FILTER. * src/dispextern.h (face_at_buffer_position): Added LFACE_ATTRIBUTE_INDEX. * src/xfaces.c (merge_face_ref): Added LFACE_ATTRIBUTE_INDEX to merge conditionally. --- diff --git a/src/dispextern.h b/src/dispextern.h index 519cc36345c..5db3ae88bf8 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -3554,8 +3554,8 @@ int lookup_derived_face (struct window *, struct frame *, void init_frame_faces (struct frame *); void free_frame_faces (struct frame *); void recompute_basic_faces (struct frame *); -int face_at_buffer_position (struct window *, ptrdiff_t, ptrdiff_t *, ptrdiff_t, - bool, int); +int face_at_buffer_position (struct window *, ptrdiff_t, ptrdiff_t *, + ptrdiff_t, bool, int, enum lface_attribute_index); int face_for_overlay_string (struct window *, ptrdiff_t, ptrdiff_t *, ptrdiff_t, bool, Lisp_Object); int face_at_string_position (struct window *, Lisp_Object, ptrdiff_t, ptrdiff_t, diff --git a/src/font.c b/src/font.c index 6bc977fd68e..e1e33ab8b22 100644 --- a/src/font.c +++ b/src/font.c @@ -3785,10 +3785,10 @@ font_at (int c, ptrdiff_t pos, struct face *face, struct window *w, if (STRINGP (string)) face_id = face_at_string_position (w, string, pos, 0, &endptr, - DEFAULT_FACE_ID, false); + DEFAULT_FACE_ID, 0); else face_id = face_at_buffer_position (w, pos, &endptr, - pos + 100, false, -1); + pos + 100, false, -1, 0); face = FACE_FROM_ID (f, face_id); } if (multibyte) @@ -3832,7 +3832,7 @@ font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit, if (NILP (string)) face_id = face_at_buffer_position (w, pos, &ignore, *limit, - false, -1); + false, -1, 0); else { face_id = @@ -4618,7 +4618,7 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0, w = XWINDOW (window); f = XFRAME (w->frame); face_id = face_at_buffer_position (w, pos, &dummy, - pos + 100, false, -1); + pos + 100, false, -1, 0); } if (! CHAR_VALID_P (c)) return Qnil; diff --git a/src/xdisp.c b/src/xdisp.c index 38a2ff66c5b..07ff4c7da7d 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -4148,15 +4148,18 @@ handle_fontified_prop (struct it *it) Faces ***********************************************************************/ -/* Set up iterator IT from face properties at its current position. - Called from handle_stop. */ - static enum prop_handled -handle_face_prop (struct it *it) +handle_face_prop_general (struct it *it, + enum lface_attribute_index attr_filter) { - int new_face_id; + int new_face_id, *face_id_ptr; ptrdiff_t next_stop; + if (attr_filter == LFACE_EXTEND_INDEX) + face_id_ptr = &(it->extend_face_id); + else + face_id_ptr = &(it->face_id); + if (!STRINGP (it->string)) { new_face_id @@ -4165,7 +4168,7 @@ handle_face_prop (struct it *it) &next_stop, (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), - false, it->base_face_id); + false, it->base_face_id, attr_filter); /* Is this a start of a run of characters with box face? Caveat: this can be called for a freshly initialized @@ -4173,13 +4176,13 @@ handle_face_prop (struct it *it) face will not change until limit, i.e. if the new face has a box, all characters up to limit will have one. But, as usual, we don't know whether limit is really the end. */ - if (new_face_id != it->face_id) + if (new_face_id != *face_id_ptr) { struct face *new_face = FACE_FROM_ID (it->f, new_face_id); /* If it->face_id is -1, old_face below will be NULL, see the definition of FACE_FROM_ID_OR_NULL. This will happen if this is the initial call that gets the face. */ - struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id); + struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, *face_id_ptr); /* If the value of face_id of the iterator is -1, we have to look in front of IT's position and see whether there is a @@ -4285,10 +4288,10 @@ handle_face_prop (struct it *it) box, all characters up to that position will have a box. But, as usual, we don't know whether that position is really the end. */ - if (new_face_id != it->face_id) + if (new_face_id != *face_id_ptr) { struct face *new_face = FACE_FROM_ID (it->f, new_face_id); - struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id); + struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, *face_id_ptr); /* If new face has a box but old face hasn't, this is the start of a run of characters with box, i.e. it has a @@ -4299,11 +4302,21 @@ handle_face_prop (struct it *it) } } - it->face_id = new_face_id; + *face_id_ptr = new_face_id; return HANDLED_NORMALLY; } +/* Set up iterator IT from face properties at its current position. + Called from handle_stop. */ + +static enum prop_handled +handle_face_prop (struct it *it) +{ + return handle_face_prop_general (it, 0); +} + + /* Return the ID of the face ``underlying'' IT's current position, which is in a string. If the iterator is associated with a buffer, return the face at IT's current buffer position. @@ -4527,7 +4540,7 @@ face_before_or_after_it_pos (struct it *it, bool before_p) face_id = face_at_buffer_position (it->w, CHARPOS (pos), &next_check_charpos, - limit, false, -1); + limit, false, -1, 0); /* Correct the face for charsets different from ASCII. Do it for the multibyte case only. The face returned above is @@ -7649,10 +7662,11 @@ get_next_display_element (struct it *it) else { next_face_id = - face_at_buffer_position (it->w, CHARPOS (pos), &ignore, + face_at_buffer_position (it->w, CHARPOS (pos), + &ignore, CHARPOS (pos) + TEXT_PROP_DISTANCE_LIMIT, - false, -1); + false, -1, 0); it->end_of_box_run_p = (FACE_FROM_ID (it->f, next_face_id)->box == FACE_NO_BOX); @@ -32068,7 +32082,7 @@ mouse_face_from_buffer_pos (Lisp_Object window, hlinfo->mouse_face_face_id = face_at_buffer_position (w, mouse_charpos, &ignore, mouse_charpos + 1, - !hlinfo->mouse_face_hidden, -1); + !hlinfo->mouse_face_hidden, -1, 0); show_mouse_face (hlinfo, DRAW_MOUSE_FACE); } diff --git a/src/xfaces.c b/src/xfaces.c index 889bf83561c..189ba1e7678 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -347,7 +347,8 @@ static struct face_cache *make_face_cache (struct frame *); static void free_face_cache (struct face_cache *); static bool merge_face_ref (struct window *w, struct frame *, Lisp_Object, Lisp_Object *, - bool, struct named_merge_point *); + bool, struct named_merge_point *, + enum lface_attribute_index); static int color_distance (Emacs_Color *x, Emacs_Color *y); #ifdef HAVE_WINDOW_SYSTEM @@ -1910,7 +1911,8 @@ get_lface_attributes (struct window *w, attrs[i] = Qunspecified; return merge_face_ref (w, f, XCDR (face_remapping), attrs, - signal_p, named_merge_points); + signal_p, named_merge_points, + 0); } } @@ -2065,7 +2067,8 @@ merge_face_vectors (struct window *w, if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX]) && !NILP (from[LFACE_INHERIT_INDEX])) merge_face_ref (w, f, from[LFACE_INHERIT_INDEX], - to, false, named_merge_points); + to, false, named_merge_points, + 0); if (FONT_SPEC_P (from[LFACE_FONT_INDEX])) { @@ -2131,7 +2134,8 @@ merge_face_vectors (struct window *w, static bool merge_named_face (struct window *w, struct frame *f, Lisp_Object face_name, Lisp_Object *to, - struct named_merge_point *named_merge_points) + struct named_merge_point *named_merge_points, + enum lface_attribute_index attr_filter) { struct named_merge_point named_merge_point; @@ -2141,9 +2145,13 @@ merge_named_face (struct window *w, { Lisp_Object from[LFACE_VECTOR_SIZE]; bool ok = get_lface_attributes (w, f, face_name, from, false, - named_merge_points); + named_merge_points); - if (ok) + eassert (attr_filter < LFACE_VECTOR_SIZE); + + if (ok && (attr_filter == 0 + || (!NILP (from[attr_filter]) + && !UNSPECIFIEDP (from[attr_filter])))) merge_face_vectors (w, f, from, to, named_merge_points); return ok; @@ -2274,6 +2282,11 @@ filter_face_ref (Lisp_Object face_ref, of ERR_MSGS). Use NAMED_MERGE_POINTS to detect loops in face inheritance or list structure; it may be 0 for most callers. + attr_filter is the index of a parameter that conditions the merging + for named faces (case 1) to only the face_ref where + lface[merge_face_ref] is non-nil. To merge unconditionally set this + value to 0. + FACE_REF may be a single face specification or a list of such specifications. Each face specification can be: @@ -2302,7 +2315,8 @@ filter_face_ref (Lisp_Object face_ref, static bool merge_face_ref (struct window *w, struct frame *f, Lisp_Object face_ref, Lisp_Object *to, - bool err_msgs, struct named_merge_point *named_merge_points) + bool err_msgs, struct named_merge_point *named_merge_points, + enum lface_attribute_index attr_filter) { bool ok = true; /* Succeed without an error? */ Lisp_Object filtered_face_ref; @@ -2514,7 +2528,8 @@ merge_face_ref (struct window *w, /* This is not really very useful; it's just like a normal face reference. */ if (! merge_face_ref (w, f, value, to, - err_msgs, named_merge_points)) + err_msgs, named_merge_points, + 0)) err = true; } else if (EQ (keyword, QCextend)) @@ -2544,16 +2559,19 @@ merge_face_ref (struct window *w, Lisp_Object next = XCDR (face_ref); if (! NILP (next)) - ok = merge_face_ref (w, f, next, to, err_msgs, named_merge_points); + ok = merge_face_ref (w, f, next, to, err_msgs, + named_merge_points, 0); - if (! merge_face_ref (w, f, first, to, err_msgs, named_merge_points)) + if (! merge_face_ref (w, f, first, to, err_msgs, + named_merge_points, 0)) ok = false; } } else { /* FACE_REF ought to be a face name. */ - ok = merge_named_face (w, f, face_ref, to, named_merge_points); + ok = merge_named_face (w, f, face_ref, to, named_merge_points, + attr_filter); if (!ok && err_msgs) add_to_log ("Invalid face reference: %s", face_ref); } @@ -4534,7 +4552,8 @@ lookup_face (struct frame *f, Lisp_Object *attr) suitable face is found, realize a new one. */ int -face_for_font (struct frame *f, Lisp_Object font_object, struct face *base_face) +face_for_font (struct frame *f, Lisp_Object font_object, + struct face *base_face) { struct face_cache *cache = FRAME_FACE_CACHE (f); unsigned hash; @@ -4769,7 +4788,7 @@ DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector, Lisp_Object lface = make_vector (LFACE_VECTOR_SIZE, Qunspecified); merge_face_ref (NULL, XFRAME (selected_frame), plist, XVECTOR (lface)->contents, - true, 0); + true, NULL, 0); return lface; } @@ -5126,7 +5145,7 @@ face for italic. */) for (i = 0; i < LFACE_VECTOR_SIZE; i++) attrs[i] = Qunspecified; - merge_face_ref (NULL, f, attributes, attrs, true, 0); + merge_face_ref (NULL, f, attributes, attrs, true, NULL, 0); def_face = FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID); if (def_face == NULL) @@ -6012,7 +6031,7 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop) Lisp_Object attrs[LFACE_VECTOR_SIZE]; struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); memcpy (attrs, default_face->lface, sizeof attrs); - merge_face_ref (NULL, f, prop, attrs, true, 0); + merge_face_ref (NULL, f, prop, attrs, true, NULL, 0); face_id = lookup_face (f, attrs); } @@ -6024,6 +6043,8 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop) which a different face is needed, as far as text properties and overlays are concerned. W is a window displaying current_buffer. + attr_filter is passed merge_face_ref. + REGION_BEG, REGION_END delimit the region, so it can be highlighted. @@ -6043,7 +6064,8 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop) int face_at_buffer_position (struct window *w, ptrdiff_t pos, ptrdiff_t *endptr, ptrdiff_t limit, - bool mouse, int base_face_id) + bool mouse, int base_face_id, + enum lface_attribute_index attr_filter) { struct frame *f = XFRAME (w->frame); Lisp_Object attrs[LFACE_VECTOR_SIZE]; @@ -6104,8 +6126,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, } /* Optimize common cases where we can use the default face. */ - if (noverlays == 0 - && NILP (prop)) + if (noverlays == 0 && NILP (prop)) { SAFE_FREE (); return default_face->id; @@ -6116,7 +6137,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, /* Merge in attributes specified via text properties. */ if (!NILP (prop)) - merge_face_ref (w, f, prop, attrs, true, 0); + merge_face_ref (w, f, prop, attrs, true, NULL, 0); /* Now merge the overlay data. */ noverlays = sort_overlays (overlay_vec, noverlays, w); @@ -6136,7 +6157,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, so discard the mouse-face text property, if any, and use the overlay property instead. */ memcpy (attrs, default_face->lface, sizeof attrs); - merge_face_ref (w, f, prop, attrs, true, 0); + merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter); } oend = OVERLAY_END (overlay_vec[i]); @@ -6153,8 +6174,9 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, ptrdiff_t oendpos; prop = Foverlay_get (overlay_vec[i], propname); + if (!NILP (prop)) - merge_face_ref (w, f, prop, attrs, true, 0); + merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter); oend = OVERLAY_END (overlay_vec[i]); oendpos = OVERLAY_POSITION (oend); @@ -6220,7 +6242,7 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos, /* Merge in attributes specified via text properties. */ if (!NILP (prop)) - merge_face_ref (w, f, prop, attrs, true, 0); + merge_face_ref (w, f, prop, attrs, true, NULL, 0); *endptr = endpos; @@ -6255,7 +6277,7 @@ int face_at_string_position (struct window *w, Lisp_Object string, ptrdiff_t pos, ptrdiff_t bufpos, ptrdiff_t *endptr, enum face_id base_face_id, - bool mouse_p) + bool mouse_p) { Lisp_Object prop, position, end, limit; struct frame *f = XFRAME (WINDOW_FRAME (w)); @@ -6299,7 +6321,7 @@ face_at_string_position (struct window *w, Lisp_Object string, /* Merge in attributes specified via text properties. */ if (!NILP (prop)) - merge_face_ref (w, f, prop, attrs, true, 0); + merge_face_ref (w, f, prop, attrs, true, NULL, 0); /* Look up a realized face with the given face attributes, or realize a new one for ASCII characters. */ @@ -6349,7 +6371,7 @@ merge_faces (struct window *w, Lisp_Object face_name, int face_id, if (!NILP (face_name)) { - if (!merge_named_face (w, f, face_name, attrs, 0)) + if (!merge_named_face (w, f, face_name, attrs, NULL, 0)) return base_face_id; } else