diff options
| author | João Távora | 2018-06-09 15:49:04 +0100 |
|---|---|---|
| committer | João Távora | 2018-06-09 15:49:04 +0100 |
| commit | 16a7bce700f4b90bd6b2d7ab4bb860a3c29cb764 (patch) | |
| tree | 48b02e12d83195e21658476dfd56caa1af71c557 /src/xfaces.c | |
| parent | 4aed7ee79cbea9963a84d5d925d39f7bc07aed98 (diff) | |
| parent | 38111b5e98380c518aeb1bb7be52b7972a248332 (diff) | |
| download | emacs-scratch/allow-custom-null-and-false-objects-in-jsonc.tar.gz emacs-scratch/allow-custom-null-and-false-objects-in-jsonc.zip | |
Merge branch 'master' into this scratch branchscratch/allow-custom-null-and-false-objects-in-jsonc
scratch/allow-custom-null-and-false-objects-in-jsonc
Diffstat (limited to 'src/xfaces.c')
| -rw-r--r-- | src/xfaces.c | 303 |
1 files changed, 236 insertions, 67 deletions
diff --git a/src/xfaces.c b/src/xfaces.c index a9c2f37e9f2..961bef7c9ce 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -350,7 +350,8 @@ static bool realize_default_face (struct frame *); | |||
| 350 | static void realize_named_face (struct frame *, Lisp_Object, int); | 350 | static void realize_named_face (struct frame *, Lisp_Object, int); |
| 351 | static struct face_cache *make_face_cache (struct frame *); | 351 | static struct face_cache *make_face_cache (struct frame *); |
| 352 | static void free_face_cache (struct face_cache *); | 352 | static void free_face_cache (struct face_cache *); |
| 353 | static bool merge_face_ref (struct frame *, Lisp_Object, Lisp_Object *, | 353 | static bool merge_face_ref (struct window *w, |
| 354 | struct frame *, Lisp_Object, Lisp_Object *, | ||
| 354 | bool, struct named_merge_point *); | 355 | bool, struct named_merge_point *); |
| 355 | static int color_distance (XColor *x, XColor *y); | 356 | static int color_distance (XColor *x, XColor *y); |
| 356 | 357 | ||
| @@ -1551,7 +1552,7 @@ the WIDTH times as wide as FACE on FRAME. */) | |||
| 1551 | { | 1552 | { |
| 1552 | /* This is of limited utility since it works with character | 1553 | /* This is of limited utility since it works with character |
| 1553 | widths. Keep it for compatibility. --gerd. */ | 1554 | widths. Keep it for compatibility. --gerd. */ |
| 1554 | int face_id = lookup_named_face (f, face, false); | 1555 | int face_id = lookup_named_face (NULL, f, face, false); |
| 1555 | struct face *width_face = FACE_FROM_ID_OR_NULL (f, face_id); | 1556 | struct face *width_face = FACE_FROM_ID_OR_NULL (f, face_id); |
| 1556 | 1557 | ||
| 1557 | if (width_face && width_face->font) | 1558 | if (width_face && width_face->font) |
| @@ -1907,19 +1908,22 @@ get_lface_attributes_no_remap (struct frame *f, Lisp_Object face_name, | |||
| 1907 | return !NILP (lface); | 1908 | return !NILP (lface); |
| 1908 | } | 1909 | } |
| 1909 | 1910 | ||
| 1910 | /* Get face attributes of face FACE_NAME from frame-local faces on frame | 1911 | /* Get face attributes of face FACE_NAME from frame-local faces on |
| 1911 | F. Store the resulting attributes in ATTRS which must point to a | 1912 | frame F. Store the resulting attributes in ATTRS which must point |
| 1912 | vector of Lisp_Objects of size LFACE_VECTOR_SIZE. If FACE_NAME is an | 1913 | to a vector of Lisp_Objects of size LFACE_VECTOR_SIZE. |
| 1913 | alias for another face, use that face's definition. | 1914 | If FACE_NAME is an alias for another face, use that face's |
| 1914 | If SIGNAL_P, signal an error if FACE_NAME does not name a face. | 1915 | definition. If SIGNAL_P, signal an error if FACE_NAME does not |
| 1915 | Otherwise, return true iff FACE_NAME is a face. */ | 1916 | name a face. Otherwise, return true iff FACE_NAME is a face. If W |
| 1916 | 1917 | is non-NULL, also consider remappings attached to the window. | |
| 1918 | */ | ||
| 1917 | static bool | 1919 | static bool |
| 1918 | get_lface_attributes (struct frame *f, Lisp_Object face_name, | 1920 | get_lface_attributes (struct window *w, |
| 1921 | struct frame *f, Lisp_Object face_name, | ||
| 1919 | Lisp_Object attrs[LFACE_VECTOR_SIZE], bool signal_p, | 1922 | Lisp_Object attrs[LFACE_VECTOR_SIZE], bool signal_p, |
| 1920 | struct named_merge_point *named_merge_points) | 1923 | struct named_merge_point *named_merge_points) |
| 1921 | { | 1924 | { |
| 1922 | Lisp_Object face_remapping; | 1925 | Lisp_Object face_remapping; |
| 1926 | eassert (w == NULL || WINDOW_XFRAME (w) == f); | ||
| 1923 | 1927 | ||
| 1924 | face_name = resolve_face_name (face_name, signal_p); | 1928 | face_name = resolve_face_name (face_name, signal_p); |
| 1925 | 1929 | ||
| @@ -1939,7 +1943,7 @@ get_lface_attributes (struct frame *f, Lisp_Object face_name, | |||
| 1939 | for (i = 1; i < LFACE_VECTOR_SIZE; ++i) | 1943 | for (i = 1; i < LFACE_VECTOR_SIZE; ++i) |
| 1940 | attrs[i] = Qunspecified; | 1944 | attrs[i] = Qunspecified; |
| 1941 | 1945 | ||
| 1942 | return merge_face_ref (f, XCDR (face_remapping), attrs, | 1946 | return merge_face_ref (w, f, XCDR (face_remapping), attrs, |
| 1943 | signal_p, named_merge_points); | 1947 | signal_p, named_merge_points); |
| 1944 | } | 1948 | } |
| 1945 | } | 1949 | } |
| @@ -2072,15 +2076,16 @@ merge_face_heights (Lisp_Object from, Lisp_Object to, Lisp_Object invalid) | |||
| 2072 | 2076 | ||
| 2073 | /* Merge two Lisp face attribute vectors on frame F, FROM and TO, and | 2077 | /* Merge two Lisp face attribute vectors on frame F, FROM and TO, and |
| 2074 | store the resulting attributes in TO, which must be already be | 2078 | store the resulting attributes in TO, which must be already be |
| 2075 | completely specified and contain only absolute attributes. Every | 2079 | completely specified and contain only absolute attributes. |
| 2076 | specified attribute of FROM overrides the corresponding attribute of | 2080 | Every specified attribute of FROM overrides the corresponding |
| 2077 | TO; relative attributes in FROM are merged with the absolute value in | 2081 | attribute of TO; relative attributes in FROM are merged with the |
| 2078 | TO and replace it. NAMED_MERGE_POINTS is used internally to detect | 2082 | absolute value in TO and replace it. NAMED_MERGE_POINTS is used |
| 2079 | loops in face inheritance/remapping; it should be 0 when called from | 2083 | internally to detect loops in face inheritance/remapping; it should |
| 2080 | other places. */ | 2084 | be 0 when called from other places. If window W is non-NULL, use W |
| 2081 | 2085 | to interpret face specifications. */ | |
| 2082 | static void | 2086 | static void |
| 2083 | merge_face_vectors (struct frame *f, Lisp_Object *from, Lisp_Object *to, | 2087 | merge_face_vectors (struct window *w, |
| 2088 | struct frame *f, Lisp_Object *from, Lisp_Object *to, | ||
| 2084 | struct named_merge_point *named_merge_points) | 2089 | struct named_merge_point *named_merge_points) |
| 2085 | { | 2090 | { |
| 2086 | int i; | 2091 | int i; |
| @@ -2093,7 +2098,8 @@ merge_face_vectors (struct frame *f, Lisp_Object *from, Lisp_Object *to, | |||
| 2093 | other code uses `unspecified' as a generic value for face attributes. */ | 2098 | other code uses `unspecified' as a generic value for face attributes. */ |
| 2094 | if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX]) | 2099 | if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX]) |
| 2095 | && !NILP (from[LFACE_INHERIT_INDEX])) | 2100 | && !NILP (from[LFACE_INHERIT_INDEX])) |
| 2096 | merge_face_ref (f, from[LFACE_INHERIT_INDEX], to, false, named_merge_points); | 2101 | merge_face_ref (w, f, from[LFACE_INHERIT_INDEX], |
| 2102 | to, false, named_merge_points); | ||
| 2097 | 2103 | ||
| 2098 | if (FONT_SPEC_P (from[LFACE_FONT_INDEX])) | 2104 | if (FONT_SPEC_P (from[LFACE_FONT_INDEX])) |
| 2099 | { | 2105 | { |
| @@ -2153,10 +2159,12 @@ merge_face_vectors (struct frame *f, Lisp_Object *from, Lisp_Object *to, | |||
| 2153 | /* Merge the named face FACE_NAME on frame F, into the vector of face | 2159 | /* Merge the named face FACE_NAME on frame F, into the vector of face |
| 2154 | attributes TO. Use NAMED_MERGE_POINTS to detect loops in face | 2160 | attributes TO. Use NAMED_MERGE_POINTS to detect loops in face |
| 2155 | inheritance. Return true if FACE_NAME is a valid face name and | 2161 | inheritance. Return true if FACE_NAME is a valid face name and |
| 2156 | merging succeeded. */ | 2162 | merging succeeded. Window W, if non-NULL, is used to filter face |
| 2163 | specifications. */ | ||
| 2157 | 2164 | ||
| 2158 | static bool | 2165 | static bool |
| 2159 | merge_named_face (struct frame *f, Lisp_Object face_name, Lisp_Object *to, | 2166 | merge_named_face (struct window *w, |
| 2167 | struct frame *f, Lisp_Object face_name, Lisp_Object *to, | ||
| 2160 | struct named_merge_point *named_merge_points) | 2168 | struct named_merge_point *named_merge_points) |
| 2161 | { | 2169 | { |
| 2162 | struct named_merge_point named_merge_point; | 2170 | struct named_merge_point named_merge_point; |
| @@ -2166,11 +2174,11 @@ merge_named_face (struct frame *f, Lisp_Object face_name, Lisp_Object *to, | |||
| 2166 | &named_merge_points)) | 2174 | &named_merge_points)) |
| 2167 | { | 2175 | { |
| 2168 | Lisp_Object from[LFACE_VECTOR_SIZE]; | 2176 | Lisp_Object from[LFACE_VECTOR_SIZE]; |
| 2169 | bool ok = get_lface_attributes (f, face_name, from, false, | 2177 | bool ok = get_lface_attributes (w, f, face_name, from, false, |
| 2170 | named_merge_points); | 2178 | named_merge_points); |
| 2171 | 2179 | ||
| 2172 | if (ok) | 2180 | if (ok) |
| 2173 | merge_face_vectors (f, from, to, named_merge_points); | 2181 | merge_face_vectors (w, f, from, to, named_merge_points); |
| 2174 | 2182 | ||
| 2175 | return ok; | 2183 | return ok; |
| 2176 | } | 2184 | } |
| @@ -2178,6 +2186,111 @@ merge_named_face (struct frame *f, Lisp_Object face_name, Lisp_Object *to, | |||
| 2178 | return false; | 2186 | return false; |
| 2179 | } | 2187 | } |
| 2180 | 2188 | ||
| 2189 | /* Determine whether the face filter FILTER evaluated in window W | ||
| 2190 | matches. W can be NULL if the window context is unknown. | ||
| 2191 | |||
| 2192 | A face filter is either nil, which always matches, or a list | ||
| 2193 | (:window PARAMETER VALUE), which matches if the current window has | ||
| 2194 | a PARAMETER EQ to VALUE. | ||
| 2195 | |||
| 2196 | If the filter is invalid, set *OK to false and, if ERR_MSGS is | ||
| 2197 | true, log an error message. */ | ||
| 2198 | static bool | ||
| 2199 | evaluate_face_filter (Lisp_Object filter, struct window *w, | ||
| 2200 | bool *ok, bool err_msgs) | ||
| 2201 | { | ||
| 2202 | Lisp_Object orig_filter = filter; | ||
| 2203 | |||
| 2204 | { | ||
| 2205 | if (NILP (filter)) | ||
| 2206 | return true; | ||
| 2207 | |||
| 2208 | if (face_filters_always_match) | ||
| 2209 | return true; | ||
| 2210 | |||
| 2211 | if (!CONSP (filter)) | ||
| 2212 | goto err; | ||
| 2213 | |||
| 2214 | if (!EQ (XCAR (filter), Qwindow_kw)) | ||
| 2215 | goto err; | ||
| 2216 | filter = XCDR (filter); | ||
| 2217 | |||
| 2218 | Lisp_Object parameter = XCAR (filter); | ||
| 2219 | filter = XCDR (filter); | ||
| 2220 | if (!CONSP (filter)) | ||
| 2221 | goto err; | ||
| 2222 | |||
| 2223 | Lisp_Object value = XCAR (filter); | ||
| 2224 | filter = XCDR (filter); | ||
| 2225 | if (!NILP (filter)) | ||
| 2226 | goto err; | ||
| 2227 | |||
| 2228 | bool match = false; | ||
| 2229 | if (w) { | ||
| 2230 | Lisp_Object found = assq_no_quit (parameter, w->window_parameters); | ||
| 2231 | if (!NILP (found) && EQ (XCDR (found), value)) | ||
| 2232 | match = true; | ||
| 2233 | } | ||
| 2234 | |||
| 2235 | return match; | ||
| 2236 | } | ||
| 2237 | |||
| 2238 | err: | ||
| 2239 | if (err_msgs) | ||
| 2240 | add_to_log ("Invalid face filter %S", orig_filter); | ||
| 2241 | *ok = false; | ||
| 2242 | return false; | ||
| 2243 | } | ||
| 2244 | |||
| 2245 | /* Determine whether FACE_REF is a "filter" face specification (case | ||
| 2246 | #4 in merge_face_ref). If it is, evaluate the filter, and if the | ||
| 2247 | filter matches, return the filtered expression. Otherwise, return | ||
| 2248 | the original expression. | ||
| 2249 | |||
| 2250 | On error, set *OK to false, having logged an error message if | ||
| 2251 | ERR_MSGS is true, with return value unspecified. | ||
| 2252 | |||
| 2253 | W is either NULL or a window used to evaluate filters. If W is | ||
| 2254 | null, no window-based face specification filter matches. | ||
| 2255 | */ | ||
| 2256 | static Lisp_Object | ||
| 2257 | filter_face_ref (Lisp_Object face_ref, | ||
| 2258 | struct window *w, | ||
| 2259 | bool *ok, | ||
| 2260 | bool err_msgs) | ||
| 2261 | { | ||
| 2262 | Lisp_Object orig_face_ref = face_ref; | ||
| 2263 | if (!CONSP (face_ref)) | ||
| 2264 | return face_ref; | ||
| 2265 | |||
| 2266 | { | ||
| 2267 | if (!EQ (XCAR (face_ref), Qfiltered_kw)) | ||
| 2268 | return face_ref; | ||
| 2269 | face_ref = XCDR (face_ref); | ||
| 2270 | |||
| 2271 | if (!CONSP (face_ref)) | ||
| 2272 | goto err; | ||
| 2273 | Lisp_Object filter = XCAR (face_ref); | ||
| 2274 | face_ref = XCDR (face_ref); | ||
| 2275 | |||
| 2276 | if (!CONSP (face_ref)) | ||
| 2277 | goto err; | ||
| 2278 | Lisp_Object filtered_face_ref = XCAR (face_ref); | ||
| 2279 | face_ref = XCDR (face_ref); | ||
| 2280 | |||
| 2281 | if (!NILP (face_ref)) | ||
| 2282 | goto err; | ||
| 2283 | |||
| 2284 | return evaluate_face_filter (filter, w, ok, err_msgs) | ||
| 2285 | ? filtered_face_ref : Qnil; | ||
| 2286 | } | ||
| 2287 | |||
| 2288 | err: | ||
| 2289 | if (err_msgs) | ||
| 2290 | add_to_log ("Invalid face ref %S", orig_face_ref); | ||
| 2291 | *ok = false; | ||
| 2292 | return Qnil; | ||
| 2293 | } | ||
| 2181 | 2294 | ||
| 2182 | /* Merge face attributes from the lisp `face reference' FACE_REF on | 2295 | /* Merge face attributes from the lisp `face reference' FACE_REF on |
| 2183 | frame F into the face attribute vector TO. If ERR_MSGS, | 2296 | frame F into the face attribute vector TO. If ERR_MSGS, |
| @@ -2199,21 +2312,44 @@ merge_named_face (struct frame *f, Lisp_Object face_name, Lisp_Object *to, | |||
| 2199 | (BACKGROUND-COLOR . COLOR) where COLOR is a color name. This is | 2312 | (BACKGROUND-COLOR . COLOR) where COLOR is a color name. This is |
| 2200 | for compatibility with 20.2. | 2313 | for compatibility with 20.2. |
| 2201 | 2314 | ||
| 2315 | 4. Conses of the form | ||
| 2316 | (:filter (:window PARAMETER VALUE) FACE-SPECIFICATION), | ||
| 2317 | which applies FACE-SPECIFICATION only if the | ||
| 2318 | given face attributes are being evaluated in the context of a | ||
| 2319 | window with a parameter named PARAMETER being EQ VALUE. | ||
| 2320 | |||
| 2321 | 5. nil, which means to merge nothing. | ||
| 2322 | |||
| 2202 | Face specifications earlier in lists take precedence over later | 2323 | Face specifications earlier in lists take precedence over later |
| 2203 | specifications. */ | 2324 | specifications. */ |
| 2204 | 2325 | ||
| 2205 | static bool | 2326 | static bool |
| 2206 | merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to, | 2327 | merge_face_ref (struct window *w, |
| 2328 | struct frame *f, Lisp_Object face_ref, Lisp_Object *to, | ||
| 2207 | bool err_msgs, struct named_merge_point *named_merge_points) | 2329 | bool err_msgs, struct named_merge_point *named_merge_points) |
| 2208 | { | 2330 | { |
| 2209 | bool ok = true; /* Succeed without an error? */ | 2331 | bool ok = true; /* Succeed without an error? */ |
| 2332 | Lisp_Object filtered_face_ref; | ||
| 2333 | |||
| 2334 | filtered_face_ref = face_ref; | ||
| 2335 | do | ||
| 2336 | { | ||
| 2337 | face_ref = filtered_face_ref; | ||
| 2338 | filtered_face_ref = filter_face_ref (face_ref, w, &ok, err_msgs); | ||
| 2339 | } while (ok && !EQ (face_ref, filtered_face_ref)); | ||
| 2340 | |||
| 2341 | if (!ok) | ||
| 2342 | return false; | ||
| 2343 | |||
| 2344 | if (NILP (face_ref)) | ||
| 2345 | return true; | ||
| 2210 | 2346 | ||
| 2211 | if (CONSP (face_ref)) | 2347 | if (CONSP (face_ref)) |
| 2212 | { | 2348 | { |
| 2213 | Lisp_Object first = XCAR (face_ref); | 2349 | Lisp_Object first = XCAR (face_ref); |
| 2214 | 2350 | ||
| 2215 | if (EQ (first, Qforeground_color) | 2351 | if (EQ (first, Qforeground_color) |
| 2216 | || EQ (first, Qbackground_color)) | 2352 | || EQ (first, Qbackground_color)) |
| 2217 | { | 2353 | { |
| 2218 | /* One of (FOREGROUND-COLOR . COLOR) or (BACKGROUND-COLOR | 2354 | /* One of (FOREGROUND-COLOR . COLOR) or (BACKGROUND-COLOR |
| 2219 | . COLOR). COLOR must be a string. */ | 2355 | . COLOR). COLOR must be a string. */ |
| @@ -2400,7 +2536,7 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to, | |||
| 2400 | { | 2536 | { |
| 2401 | /* This is not really very useful; it's just like a | 2537 | /* This is not really very useful; it's just like a |
| 2402 | normal face reference. */ | 2538 | normal face reference. */ |
| 2403 | if (! merge_face_ref (f, value, to, | 2539 | if (! merge_face_ref (w, f, value, to, |
| 2404 | err_msgs, named_merge_points)) | 2540 | err_msgs, named_merge_points)) |
| 2405 | err = true; | 2541 | err = true; |
| 2406 | } | 2542 | } |
| @@ -2424,16 +2560,16 @@ merge_face_ref (struct frame *f, Lisp_Object face_ref, Lisp_Object *to, | |||
| 2424 | Lisp_Object next = XCDR (face_ref); | 2560 | Lisp_Object next = XCDR (face_ref); |
| 2425 | 2561 | ||
| 2426 | if (! NILP (next)) | 2562 | if (! NILP (next)) |
| 2427 | ok = merge_face_ref (f, next, to, err_msgs, named_merge_points); | 2563 | ok = merge_face_ref (w, f, next, to, err_msgs, named_merge_points); |
| 2428 | 2564 | ||
| 2429 | if (! merge_face_ref (f, first, to, err_msgs, named_merge_points)) | 2565 | if (! merge_face_ref (w, f, first, to, err_msgs, named_merge_points)) |
| 2430 | ok = false; | 2566 | ok = false; |
| 2431 | } | 2567 | } |
| 2432 | } | 2568 | } |
| 2433 | else | 2569 | else |
| 2434 | { | 2570 | { |
| 2435 | /* FACE_REF ought to be a face name. */ | 2571 | /* FACE_REF ought to be a face name. */ |
| 2436 | ok = merge_named_face (f, face_ref, to, named_merge_points); | 2572 | ok = merge_named_face (w, f, face_ref, to, named_merge_points); |
| 2437 | if (!ok && err_msgs) | 2573 | if (!ok && err_msgs) |
| 2438 | add_to_log ("Invalid face reference: %s", face_ref); | 2574 | add_to_log ("Invalid face reference: %s", face_ref); |
| 2439 | } | 2575 | } |
| @@ -3701,7 +3837,7 @@ Default face attributes override any local face attributes. */) | |||
| 3701 | /* Ensure that the face vector is fully specified by merging | 3837 | /* Ensure that the face vector is fully specified by merging |
| 3702 | the previously-cached vector. */ | 3838 | the previously-cached vector. */ |
| 3703 | memcpy (attrs, oldface->lface, sizeof attrs); | 3839 | memcpy (attrs, oldface->lface, sizeof attrs); |
| 3704 | merge_face_vectors (f, lvec, attrs, 0); | 3840 | merge_face_vectors (NULL, f, lvec, attrs, 0); |
| 3705 | vcopy (local_lface, 0, attrs, LFACE_VECTOR_SIZE); | 3841 | vcopy (local_lface, 0, attrs, LFACE_VECTOR_SIZE); |
| 3706 | newface = realize_face (c, lvec, DEFAULT_FACE_ID); | 3842 | newface = realize_face (c, lvec, DEFAULT_FACE_ID); |
| 3707 | 3843 | ||
| @@ -3774,7 +3910,7 @@ return the font name used for CHARACTER. */) | |||
| 3774 | else | 3910 | else |
| 3775 | { | 3911 | { |
| 3776 | struct frame *f = decode_live_frame (frame); | 3912 | struct frame *f = decode_live_frame (frame); |
| 3777 | int face_id = lookup_named_face (f, face, true); | 3913 | int face_id = lookup_named_face (NULL, f, face, true); |
| 3778 | struct face *fface = FACE_FROM_ID_OR_NULL (f, face_id); | 3914 | struct face *fface = FACE_FROM_ID_OR_NULL (f, face_id); |
| 3779 | 3915 | ||
| 3780 | if (! fface) | 3916 | if (! fface) |
| @@ -4432,10 +4568,12 @@ face_for_font (struct frame *f, Lisp_Object font_object, struct face *base_face) | |||
| 4432 | /* Return the face id of the realized face for named face SYMBOL on | 4568 | /* Return the face id of the realized face for named face SYMBOL on |
| 4433 | frame F suitable for displaying ASCII characters. Value is -1 if | 4569 | frame F suitable for displaying ASCII characters. Value is -1 if |
| 4434 | the face couldn't be determined, which might happen if the default | 4570 | the face couldn't be determined, which might happen if the default |
| 4435 | face isn't realized and cannot be realized. */ | 4571 | face isn't realized and cannot be realized. If window W is given, |
| 4436 | 4572 | consider face remappings specified for W or for W's buffer. If W is | |
| 4573 | NULL, consider only frame-level face configuration. */ | ||
| 4437 | int | 4574 | int |
| 4438 | lookup_named_face (struct frame *f, Lisp_Object symbol, bool signal_p) | 4575 | lookup_named_face (struct window *w, struct frame *f, |
| 4576 | Lisp_Object symbol, bool signal_p) | ||
| 4439 | { | 4577 | { |
| 4440 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; | 4578 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; |
| 4441 | Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE]; | 4579 | Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE]; |
| @@ -4448,11 +4586,11 @@ lookup_named_face (struct frame *f, Lisp_Object symbol, bool signal_p) | |||
| 4448 | default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); | 4586 | default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); |
| 4449 | } | 4587 | } |
| 4450 | 4588 | ||
| 4451 | if (! get_lface_attributes (f, symbol, symbol_attrs, signal_p, 0)) | 4589 | if (! get_lface_attributes (w, f, symbol, symbol_attrs, signal_p, 0)) |
| 4452 | return -1; | 4590 | return -1; |
| 4453 | 4591 | ||
| 4454 | memcpy (attrs, default_face->lface, sizeof attrs); | 4592 | memcpy (attrs, default_face->lface, sizeof attrs); |
| 4455 | merge_face_vectors (f, symbol_attrs, attrs, 0); | 4593 | merge_face_vectors (w, f, symbol_attrs, attrs, 0); |
| 4456 | 4594 | ||
| 4457 | return lookup_face (f, attrs); | 4595 | return lookup_face (f, attrs); |
| 4458 | } | 4596 | } |
| @@ -4462,10 +4600,10 @@ lookup_named_face (struct frame *f, Lisp_Object symbol, bool signal_p) | |||
| 4462 | is FACE_ID. The return value will usually simply be FACE_ID, unless that | 4600 | is FACE_ID. The return value will usually simply be FACE_ID, unless that |
| 4463 | basic face has bee remapped via Vface_remapping_alist. This function is | 4601 | basic face has bee remapped via Vface_remapping_alist. This function is |
| 4464 | conservative: if something goes wrong, it will simply return FACE_ID | 4602 | conservative: if something goes wrong, it will simply return FACE_ID |
| 4465 | rather than signal an error. */ | 4603 | rather than signal an error. Window W, if non-NULL, is used to filter |
| 4466 | 4604 | face specifications for remapping. */ | |
| 4467 | int | 4605 | int |
| 4468 | lookup_basic_face (struct frame *f, int face_id) | 4606 | lookup_basic_face (struct window *w, struct frame *f, int face_id) |
| 4469 | { | 4607 | { |
| 4470 | Lisp_Object name, mapping; | 4608 | Lisp_Object name, mapping; |
| 4471 | int remapped_face_id; | 4609 | int remapped_face_id; |
| @@ -4505,7 +4643,7 @@ lookup_basic_face (struct frame *f, int face_id) | |||
| 4505 | 4643 | ||
| 4506 | /* If there is a remapping entry, lookup the face using NAME, which will | 4644 | /* If there is a remapping entry, lookup the face using NAME, which will |
| 4507 | handle the remapping too. */ | 4645 | handle the remapping too. */ |
| 4508 | remapped_face_id = lookup_named_face (f, name, false); | 4646 | remapped_face_id = lookup_named_face (w, f, name, false); |
| 4509 | if (remapped_face_id < 0) | 4647 | if (remapped_face_id < 0) |
| 4510 | return face_id; /* Give up. */ | 4648 | return face_id; /* Give up. */ |
| 4511 | 4649 | ||
| @@ -4603,22 +4741,23 @@ face_with_height (struct frame *f, int face_id, int height) | |||
| 4603 | attributes of the face FACE_ID for attributes that aren't | 4741 | attributes of the face FACE_ID for attributes that aren't |
| 4604 | completely specified by SYMBOL. This is like lookup_named_face, | 4742 | completely specified by SYMBOL. This is like lookup_named_face, |
| 4605 | except that the default attributes come from FACE_ID, not from the | 4743 | except that the default attributes come from FACE_ID, not from the |
| 4606 | default face. FACE_ID is assumed to be already realized. */ | 4744 | default face. FACE_ID is assumed to be already realized. |
| 4607 | 4745 | Window W, if non-NULL, filters face specifications. */ | |
| 4608 | int | 4746 | int |
| 4609 | lookup_derived_face (struct frame *f, Lisp_Object symbol, int face_id, | 4747 | lookup_derived_face (struct window *w, |
| 4748 | struct frame *f, Lisp_Object symbol, int face_id, | ||
| 4610 | bool signal_p) | 4749 | bool signal_p) |
| 4611 | { | 4750 | { |
| 4612 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; | 4751 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; |
| 4613 | Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE]; | 4752 | Lisp_Object symbol_attrs[LFACE_VECTOR_SIZE]; |
| 4614 | struct face *default_face; | 4753 | struct face *default_face; |
| 4615 | 4754 | ||
| 4616 | if (!get_lface_attributes (f, symbol, symbol_attrs, signal_p, 0)) | 4755 | if (!get_lface_attributes (w, f, symbol, symbol_attrs, signal_p, 0)) |
| 4617 | return -1; | 4756 | return -1; |
| 4618 | 4757 | ||
| 4619 | default_face = FACE_FROM_ID (f, face_id); | 4758 | default_face = FACE_FROM_ID (f, face_id); |
| 4620 | memcpy (attrs, default_face->lface, sizeof attrs); | 4759 | memcpy (attrs, default_face->lface, sizeof attrs); |
| 4621 | merge_face_vectors (f, symbol_attrs, attrs, 0); | 4760 | merge_face_vectors (w, f, symbol_attrs, attrs, 0); |
| 4622 | return lookup_face (f, attrs); | 4761 | return lookup_face (f, attrs); |
| 4623 | } | 4762 | } |
| 4624 | 4763 | ||
| @@ -4630,7 +4769,8 @@ DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector, | |||
| 4630 | Lisp_Object lface; | 4769 | Lisp_Object lface; |
| 4631 | lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE), | 4770 | lface = Fmake_vector (make_number (LFACE_VECTOR_SIZE), |
| 4632 | Qunspecified); | 4771 | Qunspecified); |
| 4633 | merge_face_ref (XFRAME (selected_frame), plist, XVECTOR (lface)->contents, | 4772 | merge_face_ref (NULL, XFRAME (selected_frame), |
| 4773 | plist, XVECTOR (lface)->contents, | ||
| 4634 | true, 0); | 4774 | true, 0); |
| 4635 | return lface; | 4775 | return lface; |
| 4636 | } | 4776 | } |
| @@ -4714,7 +4854,7 @@ x_supports_face_attributes_p (struct frame *f, | |||
| 4714 | 4854 | ||
| 4715 | memcpy (merged_attrs, def_attrs, sizeof merged_attrs); | 4855 | memcpy (merged_attrs, def_attrs, sizeof merged_attrs); |
| 4716 | 4856 | ||
| 4717 | merge_face_vectors (f, attrs, merged_attrs, 0); | 4857 | merge_face_vectors (NULL, f, attrs, merged_attrs, 0); |
| 4718 | 4858 | ||
| 4719 | face_id = lookup_face (f, merged_attrs); | 4859 | face_id = lookup_face (f, merged_attrs); |
| 4720 | face = FACE_FROM_ID_OR_NULL (f, face_id); | 4860 | face = FACE_FROM_ID_OR_NULL (f, face_id); |
| @@ -4985,7 +5125,7 @@ face for italic. */) | |||
| 4985 | 5125 | ||
| 4986 | for (i = 0; i < LFACE_VECTOR_SIZE; i++) | 5126 | for (i = 0; i < LFACE_VECTOR_SIZE; i++) |
| 4987 | attrs[i] = Qunspecified; | 5127 | attrs[i] = Qunspecified; |
| 4988 | merge_face_ref (f, attributes, attrs, true, 0); | 5128 | merge_face_ref (NULL, f, attributes, attrs, true, 0); |
| 4989 | 5129 | ||
| 4990 | def_face = FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID); | 5130 | def_face = FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID); |
| 4991 | if (def_face == NULL) | 5131 | if (def_face == NULL) |
| @@ -5354,7 +5494,7 @@ realize_named_face (struct frame *f, Lisp_Object symbol, int id) | |||
| 5354 | 5494 | ||
| 5355 | /* Merge SYMBOL's face with the default face. */ | 5495 | /* Merge SYMBOL's face with the default face. */ |
| 5356 | get_lface_attributes_no_remap (f, symbol, symbol_attrs, true); | 5496 | get_lface_attributes_no_remap (f, symbol, symbol_attrs, true); |
| 5357 | merge_face_vectors (f, symbol_attrs, attrs, 0); | 5497 | merge_face_vectors (NULL, f, symbol_attrs, attrs, 0); |
| 5358 | 5498 | ||
| 5359 | /* Realize the face. */ | 5499 | /* Realize the face. */ |
| 5360 | realize_face (c, attrs, id); | 5500 | realize_face (c, attrs, id); |
| @@ -5869,7 +6009,7 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop) | |||
| 5869 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; | 6009 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; |
| 5870 | struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); | 6010 | struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); |
| 5871 | memcpy (attrs, default_face->lface, sizeof attrs); | 6011 | memcpy (attrs, default_face->lface, sizeof attrs); |
| 5872 | merge_face_ref (f, prop, attrs, true, 0); | 6012 | merge_face_ref (NULL, f, prop, attrs, true, 0); |
| 5873 | face_id = lookup_face (f, attrs); | 6013 | face_id = lookup_face (f, attrs); |
| 5874 | } | 6014 | } |
| 5875 | 6015 | ||
| @@ -5948,7 +6088,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, | |||
| 5948 | else if (NILP (Vface_remapping_alist)) | 6088 | else if (NILP (Vface_remapping_alist)) |
| 5949 | face_id = DEFAULT_FACE_ID; | 6089 | face_id = DEFAULT_FACE_ID; |
| 5950 | else | 6090 | else |
| 5951 | face_id = lookup_basic_face (f, DEFAULT_FACE_ID); | 6091 | face_id = lookup_basic_face (w, f, DEFAULT_FACE_ID); |
| 5952 | 6092 | ||
| 5953 | default_face = FACE_FROM_ID (f, face_id); | 6093 | default_face = FACE_FROM_ID (f, face_id); |
| 5954 | } | 6094 | } |
| @@ -5966,7 +6106,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, | |||
| 5966 | 6106 | ||
| 5967 | /* Merge in attributes specified via text properties. */ | 6107 | /* Merge in attributes specified via text properties. */ |
| 5968 | if (!NILP (prop)) | 6108 | if (!NILP (prop)) |
| 5969 | merge_face_ref (f, prop, attrs, true, 0); | 6109 | merge_face_ref (w, f, prop, attrs, true, 0); |
| 5970 | 6110 | ||
| 5971 | /* Now merge the overlay data. */ | 6111 | /* Now merge the overlay data. */ |
| 5972 | noverlays = sort_overlays (overlay_vec, noverlays, w); | 6112 | noverlays = sort_overlays (overlay_vec, noverlays, w); |
| @@ -5986,7 +6126,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, | |||
| 5986 | so discard the mouse-face text property, if any, and | 6126 | so discard the mouse-face text property, if any, and |
| 5987 | use the overlay property instead. */ | 6127 | use the overlay property instead. */ |
| 5988 | memcpy (attrs, default_face->lface, sizeof attrs); | 6128 | memcpy (attrs, default_face->lface, sizeof attrs); |
| 5989 | merge_face_ref (f, prop, attrs, true, 0); | 6129 | merge_face_ref (w, f, prop, attrs, true, 0); |
| 5990 | } | 6130 | } |
| 5991 | 6131 | ||
| 5992 | oend = OVERLAY_END (overlay_vec[i]); | 6132 | oend = OVERLAY_END (overlay_vec[i]); |
| @@ -6004,7 +6144,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, | |||
| 6004 | 6144 | ||
| 6005 | prop = Foverlay_get (overlay_vec[i], propname); | 6145 | prop = Foverlay_get (overlay_vec[i], propname); |
| 6006 | if (!NILP (prop)) | 6146 | if (!NILP (prop)) |
| 6007 | merge_face_ref (f, prop, attrs, true, 0); | 6147 | merge_face_ref (w, f, prop, attrs, true, 0); |
| 6008 | 6148 | ||
| 6009 | oend = OVERLAY_END (overlay_vec[i]); | 6149 | oend = OVERLAY_END (overlay_vec[i]); |
| 6010 | oendpos = OVERLAY_POSITION (oend); | 6150 | oendpos = OVERLAY_POSITION (oend); |
| @@ -6065,12 +6205,12 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos, | |||
| 6065 | return DEFAULT_FACE_ID; | 6205 | return DEFAULT_FACE_ID; |
| 6066 | 6206 | ||
| 6067 | /* Begin with attributes from the default face. */ | 6207 | /* Begin with attributes from the default face. */ |
| 6068 | default_face = FACE_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID)); | 6208 | default_face = FACE_FROM_ID (f, lookup_basic_face (w, f, DEFAULT_FACE_ID)); |
| 6069 | memcpy (attrs, default_face->lface, sizeof attrs); | 6209 | memcpy (attrs, default_face->lface, sizeof attrs); |
| 6070 | 6210 | ||
| 6071 | /* Merge in attributes specified via text properties. */ | 6211 | /* Merge in attributes specified via text properties. */ |
| 6072 | if (!NILP (prop)) | 6212 | if (!NILP (prop)) |
| 6073 | merge_face_ref (f, prop, attrs, true, 0); | 6213 | merge_face_ref (w, f, prop, attrs, true, 0); |
| 6074 | 6214 | ||
| 6075 | *endptr = endpos; | 6215 | *endptr = endpos; |
| 6076 | 6216 | ||
| @@ -6149,7 +6289,7 @@ face_at_string_position (struct window *w, Lisp_Object string, | |||
| 6149 | 6289 | ||
| 6150 | /* Merge in attributes specified via text properties. */ | 6290 | /* Merge in attributes specified via text properties. */ |
| 6151 | if (!NILP (prop)) | 6291 | if (!NILP (prop)) |
| 6152 | merge_face_ref (f, prop, attrs, true, 0); | 6292 | merge_face_ref (w, f, prop, attrs, true, 0); |
| 6153 | 6293 | ||
| 6154 | /* Look up a realized face with the given face attributes, | 6294 | /* Look up a realized face with the given face attributes, |
| 6155 | or realize a new one for ASCII characters. */ | 6295 | or realize a new one for ASCII characters. */ |
| @@ -6159,7 +6299,7 @@ face_at_string_position (struct window *w, Lisp_Object string, | |||
| 6159 | 6299 | ||
| 6160 | /* Merge a face into a realized face. | 6300 | /* Merge a face into a realized face. |
| 6161 | 6301 | ||
| 6162 | F is frame where faces are (to be) realized. | 6302 | W is a window in the frame where faces are (to be) realized. |
| 6163 | 6303 | ||
| 6164 | FACE_NAME is named face to merge. | 6304 | FACE_NAME is named face to merge. |
| 6165 | 6305 | ||
| @@ -6173,9 +6313,10 @@ face_at_string_position (struct window *w, Lisp_Object string, | |||
| 6173 | */ | 6313 | */ |
| 6174 | 6314 | ||
| 6175 | int | 6315 | int |
| 6176 | merge_faces (struct frame *f, Lisp_Object face_name, int face_id, | 6316 | merge_faces (struct window *w, Lisp_Object face_name, int face_id, |
| 6177 | int base_face_id) | 6317 | int base_face_id) |
| 6178 | { | 6318 | { |
| 6319 | struct frame *f = WINDOW_XFRAME (w); | ||
| 6179 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; | 6320 | Lisp_Object attrs[LFACE_VECTOR_SIZE]; |
| 6180 | struct face *base_face; | 6321 | struct face *base_face; |
| 6181 | 6322 | ||
| @@ -6190,7 +6331,7 @@ merge_faces (struct frame *f, Lisp_Object face_name, int face_id, | |||
| 6190 | face_name = lface_id_to_name[face_id]; | 6331 | face_name = lface_id_to_name[face_id]; |
| 6191 | /* When called during make-frame, lookup_derived_face may fail | 6332 | /* When called during make-frame, lookup_derived_face may fail |
| 6192 | if the faces are uninitialized. Don't signal an error. */ | 6333 | if the faces are uninitialized. Don't signal an error. */ |
| 6193 | face_id = lookup_derived_face (f, face_name, base_face_id, 0); | 6334 | face_id = lookup_derived_face (w, f, face_name, base_face_id, 0); |
| 6194 | return (face_id >= 0 ? face_id : base_face_id); | 6335 | return (face_id >= 0 ? face_id : base_face_id); |
| 6195 | } | 6336 | } |
| 6196 | 6337 | ||
| @@ -6199,7 +6340,7 @@ merge_faces (struct frame *f, Lisp_Object face_name, int face_id, | |||
| 6199 | 6340 | ||
| 6200 | if (!NILP (face_name)) | 6341 | if (!NILP (face_name)) |
| 6201 | { | 6342 | { |
| 6202 | if (!merge_named_face (f, face_name, attrs, 0)) | 6343 | if (!merge_named_face (w, f, face_name, attrs, 0)) |
| 6203 | return base_face_id; | 6344 | return base_face_id; |
| 6204 | } | 6345 | } |
| 6205 | else | 6346 | else |
| @@ -6210,7 +6351,7 @@ merge_faces (struct frame *f, Lisp_Object face_name, int face_id, | |||
| 6210 | face = FACE_FROM_ID_OR_NULL (f, face_id); | 6351 | face = FACE_FROM_ID_OR_NULL (f, face_id); |
| 6211 | if (!face) | 6352 | if (!face) |
| 6212 | return base_face_id; | 6353 | return base_face_id; |
| 6213 | merge_face_vectors (f, face->lface, attrs, 0); | 6354 | merge_face_vectors (w, f, face->lface, attrs, 0); |
| 6214 | } | 6355 | } |
| 6215 | 6356 | ||
| 6216 | /* Look up a realized face with the given face attributes, | 6357 | /* Look up a realized face with the given face attributes, |
| @@ -6421,6 +6562,11 @@ syms_of_xfaces (void) | |||
| 6421 | DEFSYM (Qunspecified, "unspecified"); | 6562 | DEFSYM (Qunspecified, "unspecified"); |
| 6422 | DEFSYM (QCignore_defface, ":ignore-defface"); | 6563 | DEFSYM (QCignore_defface, ":ignore-defface"); |
| 6423 | 6564 | ||
| 6565 | /* Used for limiting character attributes to windows with specific | ||
| 6566 | characteristics. */ | ||
| 6567 | DEFSYM (Qwindow_kw, ":window"); | ||
| 6568 | DEFSYM (Qfiltered_kw, ":filtered"); | ||
| 6569 | |||
| 6424 | /* The symbol `face-alias'. A symbol having that property is an | 6570 | /* The symbol `face-alias'. A symbol having that property is an |
| 6425 | alias for another face. Value of the property is the name of | 6571 | alias for another face. Value of the property is the name of |
| 6426 | the aliased face. */ | 6572 | the aliased face. */ |
| @@ -6496,6 +6642,10 @@ syms_of_xfaces (void) | |||
| 6496 | defsubr (&Sdump_colors); | 6642 | defsubr (&Sdump_colors); |
| 6497 | #endif | 6643 | #endif |
| 6498 | 6644 | ||
| 6645 | DEFVAR_BOOL ("face-filters-always-match", face_filters_always_match, | ||
| 6646 | doc: /* Non-nil means that face filters are always deemed to | ||
| 6647 | match. Use only when evaluating face attributes. */); | ||
| 6648 | |||
| 6499 | DEFVAR_LISP ("face-new-frame-defaults", Vface_new_frame_defaults, | 6649 | DEFVAR_LISP ("face-new-frame-defaults", Vface_new_frame_defaults, |
| 6500 | doc: /* List of global face definitions (for internal use only.) */); | 6650 | doc: /* List of global face definitions (for internal use only.) */); |
| 6501 | Vface_new_frame_defaults = Qnil; | 6651 | Vface_new_frame_defaults = Qnil; |
| @@ -6544,7 +6694,7 @@ REPLACEMENT is a face specification, i.e. one of the following: | |||
| 6544 | 6694 | ||
| 6545 | (1) a face name | 6695 | (1) a face name |
| 6546 | (2) a property list of attribute/value pairs, or | 6696 | (2) a property list of attribute/value pairs, or |
| 6547 | (3) a list in which each element has the form of (1) or (2). | 6697 | (3) a list in which each element has one of the above forms. |
| 6548 | 6698 | ||
| 6549 | List values for REPLACEMENT are merged to form the final face | 6699 | List values for REPLACEMENT are merged to form the final face |
| 6550 | specification, with earlier entries taking precedence, in the same way | 6700 | specification, with earlier entries taking precedence, in the same way |
| @@ -6564,13 +6714,32 @@ causes EXTRA-FACE... or (FACE-ATTR VAL ...) to be _merged_ with the | |||
| 6564 | existing definition of FACE. Note that this isn't necessary for the | 6714 | existing definition of FACE. Note that this isn't necessary for the |
| 6565 | default face, since every face inherits from the default face. | 6715 | default face, since every face inherits from the default face. |
| 6566 | 6716 | ||
| 6567 | If this variable is made buffer-local, the face remapping takes effect | 6717 | An entry in the list can also be a filtered face expression of the |
| 6568 | only in that buffer. For instance, the mode my-mode could define a | 6718 | form: |
| 6569 | face `my-mode-default', and then in the mode setup function, do: | 6719 | |
| 6720 | (:filtered FILTER FACE-SPECIFICATION) | ||
| 6721 | |||
| 6722 | This construct applies FACE-SPECIFICATION (which can have any of the | ||
| 6723 | forms allowed for face specifications generally) only if FILTER | ||
| 6724 | matches at the moment Emacs wants to draw text with the combined face. | ||
| 6725 | |||
| 6726 | The only filters currently defined are NIL (which always matches) and | ||
| 6727 | (:window PARAMETER VALUE), which matches only in the context of a | ||
| 6728 | window with a parameter EQ-equal to VALUE. | ||
| 6729 | |||
| 6730 | An entry in the face list can also be nil, which does nothing. | ||
| 6731 | |||
| 6732 | If `face-remapping-alist' is made buffer-local, the face remapping | ||
| 6733 | takes effect only in that buffer. For instance, the mode my-mode | ||
| 6734 | could define a face `my-mode-default', and then in the mode setup | ||
| 6735 | function, do: | ||
| 6570 | 6736 | ||
| 6571 | (set (make-local-variable \\='face-remapping-alist) | 6737 | (set (make-local-variable \\='face-remapping-alist) |
| 6572 | \\='((default my-mode-default)))). | 6738 | \\='((default my-mode-default)))). |
| 6573 | 6739 | ||
| 6740 | You probably want to use the face-remap package included in Emacs | ||
| 6741 | instead of manipulating face-remapping-alist directly. | ||
| 6742 | |||
| 6574 | Because Emacs normally only redraws screen areas when the underlying | 6743 | Because Emacs normally only redraws screen areas when the underlying |
| 6575 | buffer contents change, you may need to call `redraw-display' after | 6744 | buffer contents change, you may need to call `redraw-display' after |
| 6576 | changing this variable for it to take effect. */); | 6745 | changing this variable for it to take effect. */); |