1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-28 07:45:00 +00:00

Support "replacement characters" on TTY frames

* src/nsterm.m (ns_draw_glyphless_glyph_string_foreground):
* src/pgtkterm.c (pgtk_draw_glyphless_glyph_string_foreground):
* src/haikuterm.c (haiku_draw_glyphless_glyph_string_foreground):
* src/xterm.c (x_draw_glyphless_glyph_string_foreground):
* src/w32term.c (w32_draw_glyphless_glyph_string_foreground):
* src/xdisp.c (lookup_glyphless_char_display): Handle extra-slot
of 'glyphless-char-display' that is a cons cell.
(syms_of_xdisp) <glyphless-char-display>: Update doc string.

* etc/NEWS:
* doc/lispref/display.texi (Glyphless Chars): Document the new
feature.

* lisp/faces.el (glyphless-char): Make the face stand out on TTY
frames that don't support the underline attribute.
This commit is contained in:
Eli Zaretskii 2022-08-27 11:56:00 +03:00
parent 4015d561c3
commit 56aa52c346
10 changed files with 57 additions and 17 deletions

View File

@ -8542,7 +8542,11 @@ hexadecimal notation.
@item an @acronym{ASCII} string @item an @acronym{ASCII} string
Display a box containing that string. The string should contain at Display a box containing that string. The string should contain at
most 6 @acronym{ASCII} characters. most 6 @acronym{ASCII} characters. As an exception, if the string
includes just one character, on text-mode terminals that character
will be displayed without a box; this allows to handle such
``acronyms'' as a replacement character for characters that cannot be
displayed by the terminal.
@item a cons cell @code{(@var{graphical} . @var{text})} @item a cons cell @code{(@var{graphical} . @var{text})}
Display with @var{graphical} on graphical displays, and with Display with @var{graphical} on graphical displays, and with

View File

@ -1512,7 +1512,7 @@ non-nil, the text will now be added to the Isearch instead.
*** Changes for values 'no' and 'no-ding' of 'isearch-wrap-pause'. *** Changes for values 'no' and 'no-ding' of 'isearch-wrap-pause'.
Now with these values the search will wrap around not only on repeating Now with these values the search will wrap around not only on repeating
with 'C-s C-s', but also after typing a character. with 'C-s C-s', but also after typing a character.
1
+++ +++
*** New user option 'char-fold-override'. *** New user option 'char-fold-override'.
Non-nil means that the default definitions of equivalent characters Non-nil means that the default definitions of equivalent characters
@ -1525,11 +1525,24 @@ command accepts the Unicode name of an Emoji (for example, "smiling
face" or "heart with arrow"), like 'C-x 8 e e', with minibuffer face" or "heart with arrow"), like 'C-x 8 e e', with minibuffer
completion, and adds the Emoji into the search string. completion, and adds the Emoji into the search string.
** Glyphless characters
+++ +++
** New minor mode 'glyphless-display-mode'. *** New minor mode 'glyphless-display-mode'.
This allows an easy way to toggle seeing all glyphless characters in This allows an easy way to toggle seeing all glyphless characters in
the current buffer. the current buffer.
*** The extra slot of 'glyphless-char-display' can now have cons values.
The extra slot of the 'glyphless-char-display' char-table can now have
values that are cons cells, specifying separate values for text-mode
and GUI terminals.
*** "Replacement character" feature for undisplayable characters on TTYs.
The 'acronym' method of displaying glyphless characters on text-mode
frames treats single-character acronyms specially: they are displayed
without the surrounding [..] "box", thus in effect treating such
"acronyms" as replacement characters.
** Registers ** Registers
+++ +++

View File

@ -2978,7 +2978,7 @@ bindings. See also the face `tooltip'."
:group 'help) :group 'help)
(defface glyphless-char (defface glyphless-char
'((((type tty)) :inherit underline) '((((type tty)) :inherit escape-glyph :underline t)
(((type pc)) :inherit escape-glyph) (((type pc)) :inherit escape-glyph)
(t :height 0.6)) (t :height 0.6))
"Face for displaying non-graphic characters (e.g. U+202A (LRE)). "Face for displaying non-graphic characters (e.g. U+202A (LRE)).

View File

@ -1252,6 +1252,8 @@ haiku_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
? CHAR_TABLE_REF (Vglyphless_char_display, ? CHAR_TABLE_REF (Vglyphless_char_display,
glyph->u.glyphless.ch) glyph->u.glyphless.ch)
: XCHAR_TABLE (Vglyphless_char_display)->extras[0]); : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
if (CONSP (acronym))
acronym = XCAR (acronym);
if (STRINGP (acronym)) if (STRINGP (acronym))
str = SSDATA (acronym); str = SSDATA (acronym);
} }

View File

@ -4241,6 +4241,8 @@ Function modeled after x_draw_glyph_string_box ().
? CHAR_TABLE_REF (Vglyphless_char_display, ? CHAR_TABLE_REF (Vglyphless_char_display,
glyph->u.glyphless.ch) glyph->u.glyphless.ch)
: XCHAR_TABLE (Vglyphless_char_display)->extras[0]); : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
if (CONSP (acronym))
acronym = XCAR (acronym);
if (STRINGP (acronym)) if (STRINGP (acronym))
str = SSDATA (acronym); str = SSDATA (acronym);
} }

View File

@ -1584,6 +1584,8 @@ pgtk_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
? CHAR_TABLE_REF (Vglyphless_char_display, ? CHAR_TABLE_REF (Vglyphless_char_display,
glyph->u.glyphless.ch) glyph->u.glyphless.ch)
: XCHAR_TABLE (Vglyphless_char_display)->extras[0]); : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
if (CONSP (acronym))
acronym = XCAR (acronym);
if (STRINGP (acronym)) if (STRINGP (acronym))
str = SSDATA (acronym); str = SSDATA (acronym);
} }

View File

@ -1862,12 +1862,24 @@ produce_glyphless_glyph (struct it *it, Lisp_Object acronym)
acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c); acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
if (CONSP (acronym)) if (CONSP (acronym))
acronym = XCDR (acronym); acronym = XCDR (acronym);
buf[0] = '[';
str = STRINGP (acronym) ? SSDATA (acronym) : ""; str = STRINGP (acronym) ? SSDATA (acronym) : "";
for (len = 0; len < 6 && str[len] && ASCII_CHAR_P (str[len]); len++) /* A special kludgey feature for single-character acronyms:
buf[1 + len] = str[len]; don't put them in a box, effectively treating them as a
buf[1 + len] = ']'; replacement character. */
len += 2; if (STRINGP (acronym) && SCHARS (acronym) == 1)
{
buf[0] = str[0];
len = 1;
}
else
{
buf[0] = '[';
for (len = 0;
len < 6 && str[len] && ASCII_CHAR_P (str[len]); len++)
buf[1 + len] = str[len];
buf[1 + len] = ']';
len += 2;
}
} }
else else
{ {

View File

@ -1490,6 +1490,8 @@ w32_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
? CHAR_TABLE_REF (Vglyphless_char_display, ? CHAR_TABLE_REF (Vglyphless_char_display,
glyph->u.glyphless.ch) glyph->u.glyphless.ch)
: XCHAR_TABLE (Vglyphless_char_display)->extras[0]); : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
if (CONSP (acronym))
acronym = XCAR (acronym);
if (STRINGP (acronym)) if (STRINGP (acronym))
str = SSDATA (acronym); str = SSDATA (acronym);
} }

View File

@ -7842,15 +7842,14 @@ lookup_glyphless_char_display (int c, struct it *it)
&& CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1) && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
{ {
if (c >= 0) if (c >= 0)
{ glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
if (CONSP (glyphless_method))
glyphless_method = FRAME_WINDOW_P (it->f)
? XCAR (glyphless_method)
: XCDR (glyphless_method);
}
else else
glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0]; glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
if (CONSP (glyphless_method))
glyphless_method = FRAME_WINDOW_P (it->f)
? XCAR (glyphless_method)
: XCDR (glyphless_method);
} }
retry: retry:
@ -37117,7 +37116,9 @@ GRAPHICAL and TEXT should each have one of the values listed above.
The char-table has one extra slot to control the display of a character for The char-table has one extra slot to control the display of a character for
which no font is found. This slot only takes effect on graphical terminals. which no font is found. This slot only takes effect on graphical terminals.
Its value should be an ASCII acronym string, `hex-code', `empty-box', or Its value should be an ASCII acronym string, `hex-code', `empty-box', or
`thin-space'. The default is `empty-box'. `thin-space'. It could also be a cons cell of any two of these, to specify
separate values for graphical and text terminals.
The default is `empty-box'.
If a character has a non-nil entry in an active display table, the If a character has a non-nil entry in an active display table, the
display table takes effect; in this case, Emacs does not consult display table takes effect; in this case, Emacs does not consult

View File

@ -8316,6 +8316,8 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
? CHAR_TABLE_REF (Vglyphless_char_display, ? CHAR_TABLE_REF (Vglyphless_char_display,
glyph->u.glyphless.ch) glyph->u.glyphless.ch)
: XCHAR_TABLE (Vglyphless_char_display)->extras[0]); : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
if (CONSP (acronym))
acronym = XCAR (acronym);
if (STRINGP (acronym)) if (STRINGP (acronym))
str = SSDATA (acronym); str = SSDATA (acronym);
} }