Skip to content

Commit

Permalink
Merge branch 'feature/extend_face_id'
Browse files Browse the repository at this point in the history
New face attribute :extend to control the face extension after
EOL.

necessary, # especially if it merges an updated upstream into a topic
branch.  # # Lines starting with '#' will be ignored, and an empty
message aborts # the commit.
  • Loading branch information
Ergus committed Oct 14, 2019
2 parents a122ca6 + 7a10082 commit 3d6075e
Show file tree
Hide file tree
Showing 14 changed files with 492 additions and 378 deletions.
5 changes: 5 additions & 0 deletions doc/emacs/mark.texi
Expand Up @@ -23,6 +23,11 @@ When the mark is active, we say also that the region is active; Emacs
indicates its extent by highlighting the text within it, using the
@code{region} face (@pxref{Face Customization}).

This is one of the few faces that has the @code{:extend t} attribute
by default, which implies that the same face is used to highlight the
text and space between end of line and the window border. To
highlight only the text you could set this attribute to @code{nil}.

@cindex deactivating the mark
After certain non-motion commands, including any command that
changes the text in the buffer, Emacs automatically @dfn{deactivates}
Expand Down
22 changes: 22 additions & 0 deletions doc/lispref/display.texi
Expand Up @@ -2482,6 +2482,17 @@ faces (@pxref{Displaying Faces}). If the face to inherit from is
never merges @code{:inherit} attributes. If a list of faces is used,
attributes from faces earlier in the list override those from later
faces.

@item :extend
Whether or not this face will be extended until the end of the window.
The value should be @code{t} to extend until end of the window using
this face or @code{nil} fill the space between the end of the line and
the end of the window with the default face. When a face is conformed
by merging multiple other faces; only those with @code{:extend t} will
be merged to conform a new face to extend until end of window. By
default only @code{region} and @code{hl-line} have this attribute set
to @code{t}.

@end table

@defun font-family-list &optional frame
Expand Down Expand Up @@ -2840,6 +2851,11 @@ This sets the @code{:inverse-video} attribute of @var{face} to

@deffn Command invert-face face &optional frame
This swaps the foreground and background colors of face @var{face}.
@end deffn

@deffn Command set-face-extend face extend &optional frame
This sets the @code{:extend} attribute of @var{face} to
@var{extend}.
@end deffn

The following functions examine the attributes of a face. They
Expand Down Expand Up @@ -2900,6 +2916,12 @@ This function returns non-@code{nil} if face @var{face} specifies
a non-@code{nil} @code{:inverse-video} attribute.
@end defun

@defun face-extend-p face &optional frame
This function returns non-@code{nil} if face @var{face} specifies
a non-@code{nil} @code{:extend} attribute.
@end defun


@node Displaying Faces
@subsection Displaying Faces
@cindex displaying faces
Expand Down
7 changes: 7 additions & 0 deletions etc/NEWS
Expand Up @@ -384,6 +384,13 @@ matches strings where the pattern appears as a subsequence. Put
simply, makes "foo" complete to both "barfoo" and "frodo". Add 'flex'
to 'completion-styles' or 'completion-category-overrides' to use it.

+++
** New face attribute ':extend' to control face extension at EOL.
There is a new face attribute :extend to use the face attributes to
extend after the end of the line until the end of the window. Such
:extend is set to nil by default in all faces except for 'hl-line' and
'region' because those extend until the end of the window by default.

** Connection-local variables

+++
Expand Down
6 changes: 5 additions & 1 deletion lisp/cus-face.el
Expand Up @@ -233,7 +233,11 @@
(file :tag "File"
:help-echo "Name of bitmap file."
:must-match t)))

(:extend
(choice :tag "Extend"
:help-echo "Control whether attributes should be extended after EOL."
(const :tag "Off" nil)
(const :tag "On" t)))
(:inherit
(repeat :tag "Inherit"
:help-echo "List of faces to inherit attributes from."
Expand Down
47 changes: 37 additions & 10 deletions lisp/faces.el
Expand Up @@ -342,6 +342,7 @@ is either `foreground-color', `background-color', or a keyword."
(:box (".attributeBox" . "Face.AttributeBox"))
(:underline (".attributeUnderline" . "Face.AttributeUnderline"))
(:inverse-video (".attributeInverse" . "Face.AttributeInverse"))
(:extend (".attributeExtend" . "Face.AttributeExtend"))
(:stipple
(".attributeStipple" . "Face.AttributeStipple")
(".attributeBackgroundPixmap" . "Face.AttributeBackgroundPixmap"))
Expand Down Expand Up @@ -594,6 +595,13 @@ Use `face-attribute' for finer control."
(let ((italic (face-attribute face :slant frame inherit)))
(memq italic '(italic oblique))))

(defun face-extend-p (face &optional frame inherit)
"Return non-nil if FACE specifies a non-nil extend.
If the optional argument FRAME is given, report on face FACE in that frame.
If FRAME is t, report on the defaults for face FACE (for new frames).
If FRAME is omitted or nil, use the selected frame.
Optional argument INHERIT is passed to `face-attribute'."
(eq (face-attribute face :extend frame inherit) t))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Expand Down Expand Up @@ -760,6 +768,11 @@ For convenience, attributes `:family', `:foundry', `:width',
`:height', `:weight', and `:slant' may also be set in one step
from an X font name:
`:extend'
VALUE specifies whether the FACE should be extended after EOL.
VALUE must be one of t or nil.
`:font'
Set font-related face attributes from VALUE.
Expand Down Expand Up @@ -979,6 +992,18 @@ Use `set-face-attribute' or `modify-face' for finer control."

(define-obsolete-function-alias 'set-face-italic-p 'set-face-italic "24.4")

(defun set-face-extend (face extend-p &optional frame)
"Specify whether face FACE should be extended.
EXTEND-P nil means FACE explicitly doesn't extend after EOL.
EXTEND-P t means FACE extends after EOL.
FRAME nil or not specified means change face on all frames.
Use `set-face-attribute' to \"unspecify\" underlining."
(interactive
(let ((list (read-face-and-attribute :extend)))
(list (car list) (if (cadr list) t))))
(set-face-attribute face frame :extend extend-p))


(defalias 'set-face-background-pixmap 'set-face-stipple)

Expand Down Expand Up @@ -1102,7 +1127,7 @@ an integer value."
(:slant
(mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1)))
font-slant-table))
(:inverse-video
((or :inverse-video :extend)
(mapcar #'(lambda (x) (cons (symbol-name x) x))
(internal-lisp-face-attribute-values attribute)))
((or :underline :overline :strike-through :box)
Expand Down Expand Up @@ -1147,6 +1172,7 @@ an integer value."
(:slant . "slant")
(:underline . "underline")
(:overline . "overline")
(:extend . "extend")
(:strike-through . "strike-through")
(:box . "box")
(:inverse-video . "inverse-video display")
Expand Down Expand Up @@ -1549,7 +1575,8 @@ is given, in which case return its value instead."
;; (see also realize_default_face in xfaces.c).
(append
'(:underline nil :overline nil :strike-through nil
:box nil :inverse-video nil :stipple nil :inherit nil)
:box nil :inverse-video nil :stipple nil :inherit nil
:extend nil)
;; `display-graphic-p' is unavailable when running
;; temacs, prior to loading frame.el.
(when (fboundp 'display-graphic-p)
Expand Down Expand Up @@ -2314,24 +2341,24 @@ If you set `term-file-prefix' to nil, this function does nothing."
;; if background is light.
(defface region
'((((class color) (min-colors 88) (background dark))
:background "blue3")
:background "blue3" :extend t)
(((class color) (min-colors 88) (background light) (type gtk))
:distant-foreground "gtk_selection_fg_color"
:background "gtk_selection_bg_color")
:background "gtk_selection_bg_color" :extend t)
(((class color) (min-colors 88) (background light) (type ns))
:distant-foreground "ns_selection_fg_color"
:background "ns_selection_bg_color")
:background "ns_selection_bg_color" :extend t)
(((class color) (min-colors 88) (background light))
:background "lightgoldenrod2")
:background "lightgoldenrod2" :extend t)
(((class color) (min-colors 16) (background dark))
:background "blue3")
:background "blue3" :extend t)
(((class color) (min-colors 16) (background light))
:background "lightgoldenrod2")
:background "lightgoldenrod2" :extend t)
(((class color) (min-colors 8))
:background "blue" :foreground "white")
:background "blue" :foreground "white" :extend t)
(((type tty) (class mono))
:inverse-video t)
(t :background "gray"))
(t :background "gray" :extend t))
"Basic face for highlighting the region."
:version "21.1"
:group 'basic-faces)
Expand Down
1 change: 1 addition & 0 deletions lisp/help-fns.el
Expand Up @@ -1385,6 +1385,7 @@ If FRAME is omitted or nil, use the selected frame."
(:stipple . "Stipple")
(:font . "Font")
(:fontset . "Fontset")
(:extend . "Extend")
(:inherit . "Inherit")))
(max-width (apply #'max (mapcar #'(lambda (x) (length (cdr x)))
attrs))))
Expand Down
2 changes: 1 addition & 1 deletion lisp/hl-line.el
Expand Up @@ -78,7 +78,7 @@ when `global-hl-line-sticky-flag' is non-nil.")
:group 'convenience)

(defface hl-line
'((t :inherit highlight))
'((t :inherit highlight :extend t))
"Default face for highlighting the current line in Hl-Line mode."
:version "22.1"
:group 'hl-line)
Expand Down
27 changes: 13 additions & 14 deletions src/dispextern.h
Expand Up @@ -1607,6 +1607,7 @@ enum lface_attribute_index
LFACE_INHERIT_INDEX,
LFACE_FONTSET_INDEX,
LFACE_DISTANT_FOREGROUND_INDEX,
LFACE_EXTEND_INDEX,
LFACE_VECTOR_SIZE
};

Expand All @@ -1632,6 +1633,7 @@ enum face_box_type

enum face_underline_type
{
FACE_NO_UNDERLINE = 0,
FACE_UNDER_LINE,
FACE_UNDER_WAVE
};
Expand Down Expand Up @@ -1675,11 +1677,9 @@ struct face
/* Pixel value or color index of background color. */
unsigned long background;

/* Pixel value or color index of underline color. */
/* Pixel value or color index of underline, overlined,
strike-through, or box color. */
unsigned long underline_color;

/* Pixel value or color index of overlined, strike-through, or box
color. */
unsigned long overline_color;
unsigned long strike_through_color;
unsigned long box_color;
Expand All @@ -1706,15 +1706,14 @@ struct face
ENUM_BF (face_box_type) box : 2;

/* Style of underlining. */
ENUM_BF (face_underline_type) underline_type : 1;
ENUM_BF (face_underline_type) underline : 2;

/* If `box' above specifies a 3D type, true means use box_color for
drawing shadows. */
bool_bf use_box_color_for_shadows_p : 1;

/* Non-zero if text in this face should be underlined, overlined,
strike-through or have a box drawn around it. */
bool_bf underline_p : 1;
bool_bf overline_p : 1;
bool_bf strike_through_p : 1;

Expand All @@ -1724,14 +1723,10 @@ struct face
bool_bf foreground_defaulted_p : 1;
bool_bf background_defaulted_p : 1;

/* True means that either no color is specified for underlining or that
the specified color couldn't be loaded. Use the foreground
color when drawing in that case. */
bool_bf underline_defaulted_p : 1;

/* True means that either no color is specified for the corresponding
attribute or that the specified color couldn't be loaded.
Use the foreground color when drawing in that case. */
bool_bf underline_defaulted_p : 1;
bool_bf overline_color_defaulted_p : 1;
bool_bf strike_through_color_defaulted_p : 1;
bool_bf box_color_defaulted_p : 1;
Expand Down Expand Up @@ -1867,6 +1862,9 @@ struct face_cache
? FRAME_FACE_CACHE (F)->faces_by_id[ID] \
: NULL)

#define FACE_EXTENSIBLE_P(F) \
(!NILP (F->lface[LFACE_EXTEND_INDEX]))

/* True if FACE is suitable for displaying ASCII characters. */
INLINE bool
FACE_SUITABLE_FOR_ASCII_CHAR_P (struct face *face)
Expand Down Expand Up @@ -3553,12 +3551,13 @@ 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,
ptrdiff_t *, enum face_id, bool);
ptrdiff_t *, enum face_id, bool,
enum lface_attribute_index);
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);
Expand Down
10 changes: 5 additions & 5 deletions src/font.c
Expand Up @@ -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, false, 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)
Expand Down Expand Up @@ -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 =
Expand All @@ -3841,7 +3841,7 @@ font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit,
: lookup_basic_face (w, f, DEFAULT_FACE_ID);

face_id = face_at_string_position (w, string, pos, 0, &ignore,
face_id, false);
face_id, false, 0);
}
face = FACE_FROM_ID (f, face_id);
}
Expand Down Expand Up @@ -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;
Expand Down
10 changes: 5 additions & 5 deletions src/nsterm.m
Expand Up @@ -3404,9 +3404,9 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.
return;

/* Do underline. */
if (face->underline_p)
if (face->underline)
{
if (s->face->underline_type == FACE_UNDER_WAVE)
if (s->face->underline == FACE_UNDER_WAVE)
{
if (face->underline_defaulted_p)
[defaultCol set];
Expand All @@ -3415,15 +3415,15 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors.

ns_draw_underwave (s, width, x);
}
else if (s->face->underline_type == FACE_UNDER_LINE)
else if (s->face->underline == FACE_UNDER_LINE)
{

NSRect r;
unsigned long thickness, position;

/* If the prev was underlined, match its appearance. */
if (s->prev && s->prev->face->underline_p
&& s->prev->face->underline_type == FACE_UNDER_LINE
if (s->prev
&& s->prev->face->underline == FACE_UNDER_LINE
&& s->prev->underline_thickness > 0)
{
thickness = s->prev->underline_thickness;
Expand Down

0 comments on commit 3d6075e

Please sign in to comment.