Commit 9d447fa1 authored by Daniel Colascione's avatar Daniel Colascione

Add support for per-window face remapping

Extend face specifications to support the notion of filtering to a
specific context and add a filter that limits a face specification to
windows having a certain parameter.

* src/xfaces.c:
(evaluate_face_filter,filter_face_ref): New functions.
(merge_face_ref): Ignore filtered face specifications.
(Fx_list_fonts,get_lface_attributes,merge_face_vectors)
(merge_named_face,merge_face_ref,merge_face_ref)
(Finternal_merge_in_global_face,Fface_font,lookup_named_face)
(lookup_basic_face,Fface_attributes_as_vector)
(x_supports_face_attributes_p)
(Fdisplay_supports_face_attributes_p,realize_named_face)
(compute_char_face,face_at_buffer_position)
(face_at_buffer_position,face_at_buffer_position)
(face_at_buffer_position)
(face_for_overlay_string,face_at_string_position,merge_faces):
Pass window to face machinery.
(syms_of_xfaces): Add :window and :filtered

* src/xdisp.c (init_iterator, handle_face_prop)
(handle_single_display_spec, merge_escape_glyph_face)
(merge_glyphless_glyph_face, get_next_display_element)
(next_element_from_display_vector, append_space_for_newline)
(extend_face_to_end_of_line,highlight_trailing_whitespace)
(maybe_produce_line_number)
(display_line, calc_line_height_property): Pass window to
face machinery.

* src/term.c (tty_menu_activate): Adjust to new face core
function signature.

* src/msdos.c (XMenuActivate): Adjust to new face core
function signature.

* src/fringe.c (draw_fringe_bitmap_1, Fset_fringe_bitmap_face):
Pass window to face machinery.

* src/font.c (font_range, Finternal_char_font): Pass window to
face machinery.

* src/dispnew.c (spec_glyph_lookup_face): Pass window to
face machinery.

* src/dispextern.h:
(lookup_named_face,lookup_basic_face)
(lookup_derived_face,merge_faces):
Add struct window arguments to prototypes.
parent e2a98002
......@@ -572,6 +572,11 @@ manual for more details.
* Lisp Changes in Emacs 27.1
+++
** Face specifications (of the kind used in `face-remapping-alist')
now support filters, allowing faces to vary between windows display
the same buffer.
+++
** New function assoc-delete-all.
......
......@@ -3429,11 +3429,12 @@ char *choose_face_font (struct frame *, Lisp_Object *, Lisp_Object,
#ifdef HAVE_WINDOW_SYSTEM
void prepare_face_for_display (struct frame *, struct face *);
#endif
int lookup_named_face (struct frame *, Lisp_Object, bool);
int lookup_basic_face (struct frame *, int);
int lookup_named_face (struct window *, struct frame *, Lisp_Object, bool);
int lookup_basic_face (struct window *, struct frame *, int);
int smaller_face (struct frame *, int, int);
int face_with_height (struct frame *, int, int);
int lookup_derived_face (struct frame *, Lisp_Object, int, bool);
int lookup_derived_face (struct window *, struct frame *,
Lisp_Object, int, bool);
void init_frame_faces (struct frame *);
void free_frame_faces (struct frame *);
void recompute_basic_faces (struct frame *);
......@@ -3443,7 +3444,7 @@ 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,
ptrdiff_t *, enum face_id, bool);
int merge_faces (struct frame *, Lisp_Object, int, int);
int merge_faces (struct window *, Lisp_Object, int, int);
int compute_char_face (struct frame *, int, Lisp_Object);
void free_all_realized_faces (Lisp_Object);
extern char unspecified_fg[], unspecified_bg[];
......
......@@ -2508,8 +2508,7 @@ spec_glyph_lookup_face (struct window *w, GLYPH *glyph)
/* Convert the glyph's specified face to a realized (cache) face. */
if (lface_id > 0)
{
int face_id = merge_faces (XFRAME (w->frame),
Qt, lface_id, DEFAULT_FACE_ID);
int face_id = merge_faces (w, Qt, lface_id, DEFAULT_FACE_ID);
SET_GLYPH_FACE (*glyph, face_id);
}
}
......
......@@ -3810,7 +3810,7 @@ font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit,
face_id =
NILP (Vface_remapping_alist)
? DEFAULT_FACE_ID
: lookup_basic_face (f, DEFAULT_FACE_ID);
: lookup_basic_face (w, f, DEFAULT_FACE_ID);
face_id = face_at_string_position (w, string, pos, 0, &ignore,
face_id, false);
......@@ -4559,7 +4559,7 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
CHECK_CHARACTER (ch);
c = XINT (ch);
f = XFRAME (selected_frame);
face_id = lookup_basic_face (f, DEFAULT_FACE_ID);
face_id = lookup_basic_face (NULL, f, DEFAULT_FACE_ID);
pos = -1;
}
else
......
......@@ -587,8 +587,8 @@ draw_fringe_bitmap_1 (struct window *w, struct glyph_row *row, int left_p, int o
if (face_id == DEFAULT_FACE_ID)
{
Lisp_Object face = fringe_faces[which];
face_id = NILP (face) ? lookup_named_face (f, Qfringe, false)
: lookup_derived_face (f, face, FRINGE_FACE_ID, 0);
face_id = NILP (face) ? lookup_named_face (w, f, Qfringe, false)
: lookup_derived_face (w, f, face, FRINGE_FACE_ID, 0);
if (face_id < 0)
face_id = FRINGE_FACE_ID;
}
......@@ -1633,20 +1633,10 @@ If FACE is nil, reset face to default fringe face. */)
if (!n)
error ("Undefined fringe bitmap");
/* The purpose of the following code is to signal an error if FACE
is not a face. This is for the caller's convenience only; the
redisplay code should be able to fail gracefully. Skip the check
if FRINGE_FACE_ID is unrealized (as in batch mode and during
daemon startup). */
if (!NILP (face))
{
struct frame *f = SELECTED_FRAME ();
if (FACE_FROM_ID_OR_NULL (f, FRINGE_FACE_ID)
&& lookup_derived_face (f, face, FRINGE_FACE_ID, 1) < 0)
error ("No such face");
}
/* We used to check, as a convenience to callers, for basic face
validity here, but since validity can depend on the specific
_window_ in which this buffer is being displayed, defer the check
to redisplay, which can cope with bad face specifications. */
fringe_faces[n] = face;
return Qnil;
}
......
......@@ -3063,15 +3063,15 @@ XMenuActivate (Display *foo, XMenu *menu, int *pane, int *selidx,
state = alloca (menu->panecount * sizeof (struct IT_menu_state));
screensize = screen_size * 2;
faces[0]
= lookup_derived_face (sf, intern ("msdos-menu-passive-face"),
= lookup_derived_face (NULL, sf, intern ("msdos-menu-passive-face"),
DEFAULT_FACE_ID, 1);
faces[1]
= lookup_derived_face (sf, intern ("msdos-menu-active-face"),
= lookup_derived_face (NULL, sf, intern ("msdos-menu-active-face"),
DEFAULT_FACE_ID, 1);
selectface = intern ("msdos-menu-select-face");
faces[2] = lookup_derived_face (sf, selectface,
faces[2] = lookup_derived_face (NULL, sf, selectface,
faces[0], 1);
faces[3] = lookup_derived_face (sf, selectface,
faces[3] = lookup_derived_face (NULL, sf, selectface,
faces[1], 1);
/* Make sure the menu title is always displayed with
......
......@@ -3132,15 +3132,15 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
SAFE_NALLOCA (state, 1, menu->panecount);
memset (state, 0, sizeof (*state));
faces[0]
= lookup_derived_face (sf, intern ("tty-menu-disabled-face"),
= lookup_derived_face (NULL, sf, intern ("tty-menu-disabled-face"),
DEFAULT_FACE_ID, 1);
faces[1]
= lookup_derived_face (sf, intern ("tty-menu-enabled-face"),
= lookup_derived_face (NULL, sf, intern ("tty-menu-enabled-face"),
DEFAULT_FACE_ID, 1);
selectface = intern ("tty-menu-selected-face");
faces[2] = lookup_derived_face (sf, selectface,
faces[2] = lookup_derived_face (NULL, sf, selectface,
faces[0], 1);
faces[3] = lookup_derived_face (sf, selectface,
faces[3] = lookup_derived_face (NULL, sf, selectface,
faces[1], 1);
/* Make sure the menu title is always displayed with
......
......@@ -2809,7 +2809,7 @@ init_iterator (struct it *it, struct window *w,
/* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
if (! NILP (Vface_remapping_alist))
remapped_base_face_id
= lookup_basic_face (XFRAME (w->frame), base_face_id);
= lookup_basic_face (w, XFRAME (w->frame), base_face_id);
/* Use one of the mode line rows of W's desired matrix if
appropriate. */
......@@ -4060,7 +4060,7 @@ handle_face_prop (struct it *it)
might be a big deal. */
base_face_id = it->string_from_prefix_prop_p
? (!NILP (Vface_remapping_alist)
? lookup_basic_face (it->f, DEFAULT_FACE_ID)
? lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID)
: DEFAULT_FACE_ID)
: underlying_face_id (it);
}
......@@ -4988,7 +4988,7 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
struct face *f;
f = FACE_FROM_ID (it->f,
lookup_basic_face (it->f, DEFAULT_FACE_ID));
lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID));
new_height = (XFLOATINT (it->font_height)
* XINT (f->lface[LFACE_HEIGHT_INDEX]));
}
......@@ -5175,12 +5175,12 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
if (it)
{
int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
int face_id = lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID);
if (CONSP (XCDR (XCDR (spec))))
{
Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
int face_id2 = lookup_derived_face (it->f, face_name,
int face_id2 = lookup_derived_face (it->w, it->f, face_name,
FRINGE_FACE_ID, false);
if (face_id2 >= 0)
face_id = face_id2;
......@@ -6985,7 +6985,7 @@ merge_escape_glyph_face (struct it *it)
else
{
/* Merge the `escape-glyph' face into the current face. */
face_id = merge_faces (it->f, Qescape_glyph, 0, it->face_id);
face_id = merge_faces (it->w, Qescape_glyph, 0, it->face_id);
last_escape_glyph_frame = it->f;
last_escape_glyph_face_id = it->face_id;
last_escape_glyph_merged_face_id = face_id;
......@@ -7010,7 +7010,7 @@ merge_glyphless_glyph_face (struct it *it)
else
{
/* Merge the `glyphless-char' face into the current face. */
face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
face_id = merge_faces (it->w, Qglyphless_char, 0, it->face_id);
last_glyphless_glyph_frame = it->f;
last_glyphless_glyph_face_id = it->face_id;
last_glyphless_glyph_merged_face_id = face_id;
......@@ -7184,7 +7184,7 @@ get_next_display_element (struct it *it)
}
face_id = (lface_id
? merge_faces (it->f, Qt, lface_id, it->face_id)
? merge_faces (it->w, Qt, lface_id, it->face_id)
: merge_escape_glyph_face (it));
XSETINT (it->ctl_chars[0], g);
......@@ -7199,7 +7199,7 @@ get_next_display_element (struct it *it)
if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
{
/* Merge `nobreak-space' into the current face. */
face_id = merge_faces (it->f, Qnobreak_space, 0,
face_id = merge_faces (it->w, Qnobreak_space, 0,
it->face_id);
XSETINT (it->ctl_chars[0], ' ');
ctl_len = 1;
......@@ -7212,7 +7212,7 @@ get_next_display_element (struct it *it)
if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
{
/* Merge `nobreak-space' into the current face. */
face_id = merge_faces (it->f, Qnobreak_hyphen, 0,
face_id = merge_faces (it->w, Qnobreak_hyphen, 0,
it->face_id);
XSETINT (it->ctl_chars[0], '-');
ctl_len = 1;
......@@ -7232,7 +7232,7 @@ get_next_display_element (struct it *it)
}
face_id = (lface_id
? merge_faces (it->f, Qt, lface_id, it->face_id)
? merge_faces (it->w, Qt, lface_id, it->face_id)
: merge_escape_glyph_face (it));
/* Draw non-ASCII space/hyphen with escape glyph: */
......@@ -7860,7 +7860,7 @@ next_element_from_display_vector (struct it *it)
{
int lface_id = GLYPH_CODE_FACE (gc);
if (lface_id > 0)
it->face_id = merge_faces (it->f, Qt, lface_id,
it->face_id = merge_faces (it->w, Qt, lface_id,
it->saved_face_id);
}
......@@ -7889,7 +7889,7 @@ next_element_from_display_vector (struct it *it)
GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]);
if (lface_id > 0)
next_face_id = merge_faces (it->f, Qt, lface_id,
next_face_id = merge_faces (it->w, Qt, lface_id,
it->saved_face_id);
}
}
......@@ -20084,7 +20084,7 @@ append_space_for_newline (struct it *it, bool default_face_p)
/* If the default face was remapped, be sure to use the
remapped face for the appended newline. */
if (default_face_p)
it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
it->face_id = lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID);
else if (it->face_before_selective_p)
it->face_id = it->saved_face_id;
face = FACE_FROM_ID (it->f, it->face_id);
......@@ -20231,8 +20231,9 @@ extend_face_to_end_of_line (struct it *it)
return;
/* The default face, possibly remapped. */
default_face = FACE_FROM_ID_OR_NULL (f,
lookup_basic_face (f, DEFAULT_FACE_ID));
default_face = FACE_FROM_ID_OR_NULL (
f,
lookup_basic_face (it->w, f, DEFAULT_FACE_ID));
/* Face extension extends the background and box of IT->face_id
to the end of the line. If the background equals the background
......@@ -20486,11 +20487,12 @@ trailing_whitespace_p (ptrdiff_t charpos)
}
/* Highlight trailing whitespace, if any, in ROW. */
/* Highlight trailing whitespace, if any, in row at IT. */
static void
highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
highlight_trailing_whitespace (struct it *it)
{
struct glyph_row *row = it->glyph_row;
int used = row->used[TEXT_AREA];
if (used)
......@@ -20535,7 +20537,7 @@ highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
&& glyph->u.ch == ' '))
&& trailing_whitespace_p (glyph->charpos))
{
int face_id = lookup_named_face (f, Qtrailing_whitespace, false);
int face_id = lookup_named_face (it->w, it->f, Qtrailing_whitespace, false);
if (face_id < 0)
return;
......@@ -21107,9 +21109,9 @@ maybe_produce_line_number (struct it *it)
char lnum_buf[INT_STRLEN_BOUND (ptrdiff_t) + 1];
bool beyond_zv = IT_BYTEPOS (*it) >= ZV_BYTE ? true : false;
ptrdiff_t lnum_offset = -1; /* to produce 1-based line numbers */
int lnum_face_id = merge_faces (it->f, Qline_number, 0, DEFAULT_FACE_ID);
int lnum_face_id = merge_faces (it->w, Qline_number, 0, DEFAULT_FACE_ID);
int current_lnum_face_id
= merge_faces (it->f, Qline_number_current_line, 0, DEFAULT_FACE_ID);
= merge_faces (it->w, Qline_number_current_line, 0, DEFAULT_FACE_ID);
/* Compute point's line number if needed. */
if ((EQ (Vdisplay_line_numbers, Qrelative)
|| EQ (Vdisplay_line_numbers, Qvisual)
......@@ -21559,7 +21561,8 @@ display_line (struct it *it, int cursor_vpos)
portions of the screen will clear with the default face's
background color. */
if (row->reversed_p
|| lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
|| lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID)
!= DEFAULT_FACE_ID)
extend_face_to_end_of_line (it);
break;
}
......@@ -22192,7 +22195,7 @@ display_line (struct it *it, int cursor_vpos)
/* Highlight trailing whitespace. */
if (!NILP (Vshow_trailing_whitespace))
highlight_trailing_whitespace (it->f, it->glyph_row);
highlight_trailing_whitespace (it);
/* Compute pixel dimensions of this line. */
compute_line_metrics (it);
......@@ -27862,7 +27865,7 @@ calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
int face_id;
struct face *face;
face_id = lookup_named_face (it->f, face_name, false);
face_id = lookup_named_face (it->w, it->f, face_name, false);
face = FACE_FROM_ID_OR_NULL (it->f, face_id);
if (face == NULL || ((font = face->font) == NULL))
return make_number (-1);
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment