aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog49
-rw-r--r--src/bidi.c44
-rw-r--r--src/dispextern.h3
-rw-r--r--src/editfns.c91
-rw-r--r--src/systime.h11
-rw-r--r--src/xdisp.c90
6 files changed, 175 insertions, 113 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index d21e6383764..3f9b5beeab6 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,52 @@
12011-10-20 Eli Zaretskii <eliz@gnu.org>
2
3 * dispextern.h (struct bidi_it): New member next_en_type.
4
5 * bidi.c (bidi_line_init): Initialize the next_en_type member.
6 (bidi_resolve_explicit_1): When next_en_pos is valid for the
7 current character, check also for next_en_type being WEAK_EN.
8 (bidi_resolve_weak): Don't enter the expensive loop if the current
9 position is before next_en_pos. Record the bidi type of the first
10 non-ET, non-BN character we find, in addition to its position.
11 (bidi_level_of_next_char): Invalidate next_en_type when
12 next_en_pos is over-stepped.
13
142011-10-20 Paul Eggert <eggert@cs.ucla.edu>
15
16 Time zone name fixes for non-ASCII locales (Bug#641, Bug#9794)
17 * editfns.c: Rewrite current-time-zone so that it invokes
18 the equivalent of (format-time-string "%Z") to get the time zone name.
19 This fixes a bug when the time zone name contains characters that
20 need converting from the system time locale to Emacs internal format.
21 This fixes a shortcoming that I introduced in my 1999-10-19 patch:
22 that patch fixed format-time-string to do the conversion, but
23 I forgot to fix current-time-zone.
24 (format_time_string): New function, containing most of
25 what Fformat_time_string used to contain.
26 (Fformat_time_string): Rewrite in terms of format_time_string.
27 This doesn't change this function's behavior.
28 (current-time-zone): Rewrite to use format_time_string.
29 This fixes the bug reported by Michael Schierl in
30 <http://lists.gnu.org/archive/html/emacs-devel/2007-06/msg00334.html>.
31 Jason Rumney's 2007-06-07 change worked around this bug, but
32 didn't fix it.
33 * systime.h (tzname, timezone): Remove no-longer-used declarations.
34
352011-10-19 Eli Zaretskii <eliz@gnu.org>
36
37 * xdisp.c (start_display): If the character at POS is displayed
38 via a display vector, reset IT->current.dpvec_index to zero.
39 (try_window_reusing_current_matrix): If a line ends in a display
40 vector or the next line starts in a display vector, continue
41 redrawing the window even though the character position of
42 start_row was reached.
43 (Bug#9771, part 2)
44
452011-10-18 Chong Yidong <cyd@gnu.org>
46
47 * xdisp.c (get_next_display_element): Handle U+2010 and U+2011
48 with nobreak-char-display too.
49
12011-10-18 Eli Zaretskii <eliz@gnu.org> 502011-10-18 Eli Zaretskii <eliz@gnu.org>
2 51
3 Fix part 3 of bug#9771. 52 Fix part 3 of bug#9771.
diff --git a/src/bidi.c b/src/bidi.c
index 29e3c817318..e688637a408 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -849,6 +849,7 @@ bidi_line_init (struct bidi_it *bidi_it)
849 /* Setting this to zero will force its recomputation the first time 849 /* Setting this to zero will force its recomputation the first time
850 we need it for W5. */ 850 we need it for W5. */
851 bidi_it->next_en_pos = 0; 851 bidi_it->next_en_pos = 0;
852 bidi_it->next_en_type = UNKNOWN_BT;
852 bidi_it->next_for_ws.type = UNKNOWN_BT; 853 bidi_it->next_for_ws.type = UNKNOWN_BT;
853 bidi_set_sor_type (bidi_it, 854 bidi_set_sor_type (bidi_it,
854 (bidi_it->paragraph_dir == R2L ? 1 : 0), 855 (bidi_it->paragraph_dir == R2L ? 1 : 0),
@@ -1437,7 +1438,8 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
1437 } 1438 }
1438 } 1439 }
1439 else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ 1440 else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */
1440 || bidi_it->next_en_pos > bidi_it->charpos) 1441 || (bidi_it->next_en_pos > bidi_it->charpos
1442 && bidi_it->next_en_type == WEAK_EN))
1441 type = WEAK_EN; 1443 type = WEAK_EN;
1442 break; 1444 break;
1443 case LRE: /* X3 */ 1445 case LRE: /* X3 */
@@ -1473,7 +1475,8 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
1473 } 1475 }
1474 } 1476 }
1475 else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ 1477 else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */
1476 || bidi_it->next_en_pos > bidi_it->charpos) 1478 || (bidi_it->next_en_pos > bidi_it->charpos
1479 && bidi_it->next_en_type == WEAK_EN))
1477 type = WEAK_EN; 1480 type = WEAK_EN;
1478 break; 1481 break;
1479 case PDF: /* X7 */ 1482 case PDF: /* X7 */
@@ -1499,7 +1502,8 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it)
1499 } 1502 }
1500 } 1503 }
1501 else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */ 1504 else if (bidi_it->prev.type_after_w1 == WEAK_EN /* W5/Retaining */
1502 || bidi_it->next_en_pos > bidi_it->charpos) 1505 || (bidi_it->next_en_pos > bidi_it->charpos
1506 && bidi_it->next_en_type == WEAK_EN))
1503 type = WEAK_EN; 1507 type = WEAK_EN;
1504 break; 1508 break;
1505 default: 1509 default:
@@ -1731,10 +1735,15 @@ bidi_resolve_weak (struct bidi_it *bidi_it)
1731 else if (type == WEAK_ET /* W5: ET with EN before or after it */ 1735 else if (type == WEAK_ET /* W5: ET with EN before or after it */
1732 || type == WEAK_BN) /* W5/Retaining */ 1736 || type == WEAK_BN) /* W5/Retaining */
1733 { 1737 {
1734 if (bidi_it->prev.type_after_w1 == WEAK_EN /* ET/BN w/EN before it */ 1738 if (bidi_it->prev.type_after_w1 == WEAK_EN) /* ET/BN w/EN before it */
1735 || bidi_it->next_en_pos > bidi_it->charpos)
1736 type = WEAK_EN; 1739 type = WEAK_EN;
1737 else if (bidi_it->next_en_pos >=0) /* W5: ET/BN with EN after it. */ 1740 else if (bidi_it->next_en_pos > bidi_it->charpos
1741 && bidi_it->next_en_type != WEAK_BN)
1742 {
1743 if (bidi_it->next_en_type == WEAK_EN) /* ET/BN with EN after it */
1744 type = WEAK_EN;
1745 }
1746 else if (bidi_it->next_en_pos >=0)
1738 { 1747 {
1739 EMACS_INT en_pos = bidi_it->charpos + bidi_it->nchars; 1748 EMACS_INT en_pos = bidi_it->charpos + bidi_it->nchars;
1740 const unsigned char *s = (STRINGP (bidi_it->string.lstring) 1749 const unsigned char *s = (STRINGP (bidi_it->string.lstring)
@@ -1763,25 +1772,27 @@ bidi_resolve_weak (struct bidi_it *bidi_it)
1763 en_pos = bidi_it->charpos; 1772 en_pos = bidi_it->charpos;
1764 bidi_copy_it (bidi_it, &saved_it); 1773 bidi_copy_it (bidi_it, &saved_it);
1765 } 1774 }
1775 /* Remember this position, to speed up processing of the
1776 next ETs. */
1777 bidi_it->next_en_pos = en_pos;
1766 if (type_of_next == WEAK_EN) 1778 if (type_of_next == WEAK_EN)
1767 { 1779 {
1768 /* If the last strong character is AL, the EN we've 1780 /* If the last strong character is AL, the EN we've
1769 found will become AN when we get to it (W2). */ 1781 found will become AN when we get to it (W2). */
1770 if (bidi_it->last_strong.type_after_w1 != STRONG_AL) 1782 if (bidi_it->last_strong.type_after_w1 == STRONG_AL)
1771 { 1783 type_of_next = WEAK_AN;
1772 type = WEAK_EN;
1773 /* Remember this EN position, to speed up processing
1774 of the next ETs. */
1775 bidi_it->next_en_pos = en_pos;
1776 }
1777 else if (type == WEAK_BN) 1784 else if (type == WEAK_BN)
1778 type = NEUTRAL_ON; /* W6/Retaining */ 1785 type = NEUTRAL_ON; /* W6/Retaining */
1786 else
1787 type = WEAK_EN;
1779 } 1788 }
1780 else if (type_of_next == NEUTRAL_B) 1789 else if (type_of_next == NEUTRAL_B)
1781 /* Record the fact that there are no more ENs from 1790 /* Record the fact that there are no more ENs from
1782 here to the end of paragraph, to avoid entering the 1791 here to the end of paragraph, to avoid entering the
1783 loop above ever again in this paragraph. */ 1792 loop above ever again in this paragraph. */
1784 bidi_it->next_en_pos = -1; 1793 bidi_it->next_en_pos = -1;
1794 /* Record the type of the character where we ended our search. */
1795 bidi_it->next_en_type = type_of_next;
1785 } 1796 }
1786 } 1797 }
1787 } 1798 }
@@ -2053,7 +2064,10 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
2053 bidi_it->next_for_neutral.type = UNKNOWN_BT; 2064 bidi_it->next_for_neutral.type = UNKNOWN_BT;
2054 if (bidi_it->next_en_pos >= 0 2065 if (bidi_it->next_en_pos >= 0
2055 && bidi_it->charpos >= bidi_it->next_en_pos) 2066 && bidi_it->charpos >= bidi_it->next_en_pos)
2056 bidi_it->next_en_pos = 0; 2067 {
2068 bidi_it->next_en_pos = 0;
2069 bidi_it->next_en_type = UNKNOWN_BT;
2070 }
2057 if (bidi_it->next_for_ws.type != UNKNOWN_BT 2071 if (bidi_it->next_for_ws.type != UNKNOWN_BT
2058 && bidi_it->charpos >= bidi_it->next_for_ws.charpos) 2072 && bidi_it->charpos >= bidi_it->next_for_ws.charpos)
2059 bidi_it->next_for_ws.type = UNKNOWN_BT; 2073 bidi_it->next_for_ws.type = UNKNOWN_BT;
@@ -2179,7 +2193,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
2179 } 2193 }
2180 2194
2181 /* Resolve implicit levels, with a twist: PDFs get the embedding 2195 /* Resolve implicit levels, with a twist: PDFs get the embedding
2182 level of the enbedding they terminate. See below for the 2196 level of the embedding they terminate. See below for the
2183 reason. */ 2197 reason. */
2184 if (bidi_it->orig_type == PDF 2198 if (bidi_it->orig_type == PDF
2185 /* Don't do this if this formatting code didn't change the 2199 /* Don't do this if this formatting code didn't change the
diff --git a/src/dispextern.h b/src/dispextern.h
index bdc5008c94c..40e41923554 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1866,7 +1866,8 @@ struct bidi_it {
1866 struct bidi_saved_info next_for_neutral; /* surrounding characters for... */ 1866 struct bidi_saved_info next_for_neutral; /* surrounding characters for... */
1867 struct bidi_saved_info prev_for_neutral; /* ...resolving neutrals */ 1867 struct bidi_saved_info prev_for_neutral; /* ...resolving neutrals */
1868 struct bidi_saved_info next_for_ws; /* character after sequence of ws */ 1868 struct bidi_saved_info next_for_ws; /* character after sequence of ws */
1869 EMACS_INT next_en_pos; /* position of next EN char for ET */ 1869 EMACS_INT next_en_pos; /* pos. of next char for determining ET type */
1870 bidi_type_t next_en_type; /* type of char at next_en_pos */
1870 EMACS_INT ignore_bn_limit; /* position until which to ignore BNs */ 1871 EMACS_INT ignore_bn_limit; /* position until which to ignore BNs */
1871 bidi_dir_t sor; /* direction of start-of-run in effect */ 1872 bidi_dir_t sor; /* direction of start-of-run in effect */
1872 int scan_dir; /* direction of text scan, 1: forw, -1: back */ 1873 int scan_dir; /* direction of text scan, 1: forw, -1: back */
diff --git a/src/editfns.c b/src/editfns.c
index 5f89391ce22..83cd4bd5535 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -85,6 +85,8 @@ extern Lisp_Object w32_get_internal_run_time (void);
85#endif 85#endif
86 86
87static void time_overflow (void) NO_RETURN; 87static void time_overflow (void) NO_RETURN;
88static Lisp_Object format_time_string (char const *, ptrdiff_t, Lisp_Object,
89 int, time_t *, struct tm **);
88static int tm_diff (struct tm *, struct tm *); 90static int tm_diff (struct tm *, struct tm *);
89static void update_buffer_properties (EMACS_INT, EMACS_INT); 91static void update_buffer_properties (EMACS_INT, EMACS_INT);
90 92
@@ -1700,33 +1702,41 @@ For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z".
1700usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */) 1702usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */)
1701 (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal) 1703 (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal)
1702{ 1704{
1703 time_t value; 1705 time_t t;
1706 struct tm *tm;
1707
1708 CHECK_STRING (format_string);
1709 format_string = code_convert_string_norecord (format_string,
1710 Vlocale_coding_system, 1);
1711 return format_time_string (SSDATA (format_string), SBYTES (format_string),
1712 timeval, ! NILP (universal), &t, &tm);
1713}
1714
1715static Lisp_Object
1716format_time_string (char const *format, ptrdiff_t formatlen,
1717 Lisp_Object timeval, int ut, time_t *tval, struct tm **tmp)
1718{
1704 ptrdiff_t size; 1719 ptrdiff_t size;
1705 int usec; 1720 int usec;
1706 int ns; 1721 int ns;
1707 struct tm *tm; 1722 struct tm *tm;
1708 int ut = ! NILP (universal);
1709
1710 CHECK_STRING (format_string);
1711 1723
1712 if (! (lisp_time_argument (timeval, &value, &usec) 1724 if (! (lisp_time_argument (timeval, tval, &usec)
1713 && 0 <= usec && usec < 1000000)) 1725 && 0 <= usec && usec < 1000000))
1714 error ("Invalid time specification"); 1726 error ("Invalid time specification");
1715 ns = usec * 1000; 1727 ns = usec * 1000;
1716 1728
1717 format_string = code_convert_string_norecord (format_string,
1718 Vlocale_coding_system, 1);
1719
1720 /* This is probably enough. */ 1729 /* This is probably enough. */
1721 size = SBYTES (format_string); 1730 size = formatlen;
1722 if (size <= (STRING_BYTES_BOUND - 50) / 6) 1731 if (size <= (STRING_BYTES_BOUND - 50) / 6)
1723 size = size * 6 + 50; 1732 size = size * 6 + 50;
1724 1733
1725 BLOCK_INPUT; 1734 BLOCK_INPUT;
1726 tm = ut ? gmtime (&value) : localtime (&value); 1735 tm = ut ? gmtime (tval) : localtime (tval);
1727 UNBLOCK_INPUT; 1736 UNBLOCK_INPUT;
1728 if (! tm) 1737 if (! tm)
1729 time_overflow (); 1738 time_overflow ();
1739 *tmp = tm;
1730 1740
1731 synchronize_system_time_locale (); 1741 synchronize_system_time_locale ();
1732 1742
@@ -1737,9 +1747,7 @@ usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */)
1737 1747
1738 buf[0] = '\1'; 1748 buf[0] = '\1';
1739 BLOCK_INPUT; 1749 BLOCK_INPUT;
1740 result = emacs_nmemftime (buf, size, SSDATA (format_string), 1750 result = emacs_nmemftime (buf, size, format, formatlen, tm, ut, ns);
1741 SBYTES (format_string),
1742 tm, ut, ns);
1743 UNBLOCK_INPUT; 1751 UNBLOCK_INPUT;
1744 if ((result > 0 && result < size) || (result == 0 && buf[0] == '\0')) 1752 if ((result > 0 && result < size) || (result == 0 && buf[0] == '\0'))
1745 return code_convert_string_norecord (make_unibyte_string (buf, result), 1753 return code_convert_string_norecord (make_unibyte_string (buf, result),
@@ -1747,9 +1755,7 @@ usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */)
1747 1755
1748 /* If buffer was too small, make it bigger and try again. */ 1756 /* If buffer was too small, make it bigger and try again. */
1749 BLOCK_INPUT; 1757 BLOCK_INPUT;
1750 result = emacs_nmemftime (NULL, (size_t) -1, 1758 result = emacs_nmemftime (NULL, (size_t) -1, format, formatlen,
1751 SSDATA (format_string),
1752 SBYTES (format_string),
1753 tm, ut, ns); 1759 tm, ut, ns);
1754 UNBLOCK_INPUT; 1760 UNBLOCK_INPUT;
1755 if (STRING_BYTES_BOUND <= result) 1761 if (STRING_BYTES_BOUND <= result)
@@ -1994,51 +2000,34 @@ the data it can't find. */)
1994{ 2000{
1995 time_t value; 2001 time_t value;
1996 struct tm *t; 2002 struct tm *t;
1997 struct tm gmt; 2003 struct tm localtm;
1998 2004 struct tm *localt;
1999 if (!lisp_time_argument (specified_time, &value, NULL)) 2005 Lisp_Object zone_offset, zone_name;
2000 t = NULL; 2006
2001 else 2007 zone_offset = Qnil;
2002 { 2008 zone_name = format_time_string ("%Z", sizeof "%Z" - 1, specified_time,
2003 BLOCK_INPUT; 2009 0, &value, &localt);
2004 t = gmtime (&value); 2010 localtm = *localt;
2005 if (t) 2011 BLOCK_INPUT;
2006 { 2012 t = gmtime (&value);
2007 gmt = *t; 2013 UNBLOCK_INPUT;
2008 t = localtime (&value);
2009 }
2010 UNBLOCK_INPUT;
2011 }
2012 2014
2013 if (t) 2015 if (t)
2014 { 2016 {
2015 int offset = tm_diff (t, &gmt); 2017 int offset = tm_diff (&localtm, t);
2016 char *s = 0; 2018 zone_offset = make_number (offset);
2017 char buf[sizeof "+00" + INT_STRLEN_BOUND (int)]; 2019 if (SCHARS (zone_name) == 0)
2018
2019#ifdef HAVE_TM_ZONE
2020 if (t->tm_zone)
2021 s = (char *)t->tm_zone;
2022#else /* not HAVE_TM_ZONE */
2023#ifdef HAVE_TZNAME
2024 if (t->tm_isdst == 0 || t->tm_isdst == 1)
2025 s = tzname[t->tm_isdst];
2026#endif
2027#endif /* not HAVE_TM_ZONE */
2028
2029 if (!s)
2030 { 2020 {
2031 /* No local time zone name is available; use "+-NNNN" instead. */ 2021 /* No local time zone name is available; use "+-NNNN" instead. */
2032 int m = offset / 60; 2022 int m = offset / 60;
2033 int am = offset < 0 ? - m : m; 2023 int am = offset < 0 ? - m : m;
2024 char buf[sizeof "+00" + INT_STRLEN_BOUND (int)];
2034 sprintf (buf, "%c%02d%02d", (offset < 0 ? '-' : '+'), am/60, am%60); 2025 sprintf (buf, "%c%02d%02d", (offset < 0 ? '-' : '+'), am/60, am%60);
2035 s = buf; 2026 zone_name = build_string (buf);
2036 } 2027 }
2037
2038 return Fcons (make_number (offset), Fcons (build_string (s), Qnil));
2039 } 2028 }
2040 else 2029
2041 return Fmake_list (make_number (2), Qnil); 2030 return list2 (zone_offset, zone_name);
2042} 2031}
2043 2032
2044/* This holds the value of `environ' produced by the previous 2033/* This holds the value of `environ' produced by the previous
diff --git a/src/systime.h b/src/systime.h
index bed9ed4aa71..b90372dbe20 100644
--- a/src/systime.h
+++ b/src/systime.h
@@ -38,17 +38,6 @@ typedef unsigned long Time;
38# endif 38# endif
39#endif 39#endif
40 40
41#ifdef HAVE_TZNAME
42#ifndef tzname /* For SGI. */
43extern char *tzname[]; /* RS6000 and others want it this way. */
44#endif
45#endif
46
47/* SVr4 doesn't actually declare this in its #include files. */
48#ifdef USG5_4
49extern time_t timezone;
50#endif
51
52/* On some configurations (hpux8.0, X11R4), sys/time.h and X11/Xos.h 41/* On some configurations (hpux8.0, X11R4), sys/time.h and X11/Xos.h
53 disagree about the name of the guard symbol. */ 42 disagree about the name of the guard symbol. */
54#ifdef HPUX 43#ifdef HPUX
diff --git a/src/xdisp.c b/src/xdisp.c
index 1f4c98f8388..e0b36dbe100 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2856,6 +2856,13 @@ start_display (struct it *it, struct window *w, struct text_pos pos)
2856 2856
2857 it->continuation_lines_width += it->current_x; 2857 it->continuation_lines_width += it->current_x;
2858 } 2858 }
2859 /* If the character at POS is displayed via a display
2860 vector, move_it_to above stops at the final glyph of
2861 IT->dpvec. To make the caller redisplay that character
2862 again (a.k.a. start at POS), we need to reset the
2863 dpvec_index to the beginning of IT->dpvec. */
2864 else if (it->current.dpvec_index >= 0)
2865 it->current.dpvec_index = 0;
2859 2866
2860 /* We're starting a new display line, not affected by the 2867 /* We're starting a new display line, not affected by the
2861 height of the continued line, so clear the appropriate 2868 height of the continued line, so clear the appropriate
@@ -6409,8 +6416,8 @@ get_next_display_element (struct it *it)
6409 { 6416 {
6410 Lisp_Object dv; 6417 Lisp_Object dv;
6411 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte); 6418 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
6412 enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen } 6419 int nonascii_space_p = 0;
6413 nbsp_or_shy = char_is_other; 6420 int nonascii_hyphen_p = 0;
6414 int c = it->c; /* This is the character to display. */ 6421 int c = it->c; /* This is the character to display. */
6415 6422
6416 if (! it->multibyte_p && ! ASCII_CHAR_P (c)) 6423 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
@@ -6462,10 +6469,15 @@ get_next_display_element (struct it *it)
6462 goto get_next; 6469 goto get_next;
6463 } 6470 }
6464 6471
6472 /* If `nobreak-char-display' is non-nil, we display
6473 non-ASCII spaces and hyphens specially. */
6465 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display)) 6474 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
6466 nbsp_or_shy = (c == 0xA0 ? char_is_nbsp 6475 {
6467 : c == 0xAD ? char_is_soft_hyphen 6476 if (c == 0xA0)
6468 : char_is_other); 6477 nonascii_space_p = 1;
6478 else if (c == 0xAD || c == 0x2010 || c == 0x2011)
6479 nonascii_hyphen_p = 1;
6480 }
6469 6481
6470 /* Translate control characters into `\003' or `^C' form. 6482 /* Translate control characters into `\003' or `^C' form.
6471 Control characters coming from a display table entry are 6483 Control characters coming from a display table entry are
@@ -6473,7 +6485,8 @@ get_next_display_element (struct it *it)
6473 the translation. This could easily be changed but I 6485 the translation. This could easily be changed but I
6474 don't believe that it is worth doing. 6486 don't believe that it is worth doing.
6475 6487
6476 NBSP and SOFT-HYPEN are property translated too. 6488 The characters handled by `nobreak-char-display' must be
6489 translated too.
6477 6490
6478 Non-printable characters and raw-byte characters are also 6491 Non-printable characters and raw-byte characters are also
6479 translated to octal form. */ 6492 translated to octal form. */
@@ -6484,14 +6497,15 @@ get_next_display_element (struct it *it)
6484 && it->glyph_row 6497 && it->glyph_row
6485 && (it->glyph_row->mode_line_p || it->avoid_cursor_p)) 6498 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
6486 || (c != '\n' && c != '\t')) 6499 || (c != '\n' && c != '\t'))
6487 : (nbsp_or_shy 6500 : (nonascii_space_p
6501 || nonascii_hyphen_p
6488 || CHAR_BYTE8_P (c) 6502 || CHAR_BYTE8_P (c)
6489 || ! CHAR_PRINTABLE_P (c)))) 6503 || ! CHAR_PRINTABLE_P (c))))
6490 { 6504 {
6491 /* C is a control character, NBSP, SOFT-HYPEN, raw-byte, 6505 /* C is a control character, non-ASCII space/hyphen,
6492 or a non-printable character which must be displayed 6506 raw-byte, or a non-printable character which must be
6493 either as '\003' or as `^C' where the '\\' and '^' 6507 displayed either as '\003' or as `^C' where the '\\'
6494 can be defined in the display table. Fill 6508 and '^' can be defined in the display table. Fill
6495 IT->ctl_chars with glyphs for what we have to 6509 IT->ctl_chars with glyphs for what we have to
6496 display. Then, set IT->dpvec to these glyphs. */ 6510 display. Then, set IT->dpvec to these glyphs. */
6497 Lisp_Object gc; 6511 Lisp_Object gc;
@@ -6540,17 +6554,14 @@ get_next_display_element (struct it *it)
6540 goto display_control; 6554 goto display_control;
6541 } 6555 }
6542 6556
6543 /* Handle non-break space in the mode where it only gets 6557 /* Handle non-ascii space in the mode where it only gets
6544 highlighting. */ 6558 highlighting. */
6545 6559
6546 if (EQ (Vnobreak_char_display, Qt) 6560 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
6547 && nbsp_or_shy == char_is_nbsp)
6548 { 6561 {
6549 /* Merge the no-break-space face into the current face. */ 6562 /* Merge `nobreak-space' into the current face. */
6550 face_id = merge_faces (it->f, Qnobreak_space, 0, 6563 face_id = merge_faces (it->f, Qnobreak_space, 0,
6551 it->face_id); 6564 it->face_id);
6552
6553 c = ' ';
6554 XSETINT (it->ctl_chars[0], ' '); 6565 XSETINT (it->ctl_chars[0], ' ');
6555 ctl_len = 1; 6566 ctl_len = 1;
6556 goto display_control; 6567 goto display_control;
@@ -6590,25 +6601,21 @@ get_next_display_element (struct it *it)
6590 last_escape_glyph_merged_face_id = face_id; 6601 last_escape_glyph_merged_face_id = face_id;
6591 } 6602 }
6592 6603
6593 /* Handle soft hyphens in the mode where they only get 6604 /* Draw non-ASCII hyphen with just highlighting: */
6594 highlighting. */
6595 6605
6596 if (EQ (Vnobreak_char_display, Qt) 6606 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
6597 && nbsp_or_shy == char_is_soft_hyphen)
6598 { 6607 {
6599 XSETINT (it->ctl_chars[0], '-'); 6608 XSETINT (it->ctl_chars[0], '-');
6600 ctl_len = 1; 6609 ctl_len = 1;
6601 goto display_control; 6610 goto display_control;
6602 } 6611 }
6603 6612
6604 /* Handle non-break space and soft hyphen 6613 /* Draw non-ASCII space/hyphen with escape glyph: */
6605 with the escape glyph. */
6606 6614
6607 if (nbsp_or_shy) 6615 if (nonascii_space_p || nonascii_hyphen_p)
6608 { 6616 {
6609 XSETINT (it->ctl_chars[0], escape_glyph); 6617 XSETINT (it->ctl_chars[0], escape_glyph);
6610 c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-'); 6618 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
6611 XSETINT (it->ctl_chars[1], c);
6612 ctl_len = 2; 6619 ctl_len = 2;
6613 goto display_control; 6620 goto display_control;
6614 } 6621 }
@@ -16146,13 +16153,20 @@ try_window_reusing_current_matrix (struct window *w)
16146 16153
16147 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix); 16154 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
16148 } 16155 }
16149 /* If we have reached alignment, 16156 /* If we have reached alignment, we can copy the rest of the
16150 we can copy the rest of the rows. */ 16157 rows. */
16151 if (IT_CHARPOS (it) == CHARPOS (start)) 16158 if (IT_CHARPOS (it) == CHARPOS (start)
16159 /* Don't accept "alignment" inside a display vector,
16160 since start_row could have started in the middle of
16161 that same display vector (thus their character
16162 positions match), and we have no way of telling if
16163 that is the case. */
16164 && it.current.dpvec_index < 0)
16152 break; 16165 break;
16153 16166
16154 if (display_line (&it)) 16167 if (display_line (&it))
16155 last_text_row = it.glyph_row - 1; 16168 last_text_row = it.glyph_row - 1;
16169
16156 } 16170 }
16157 16171
16158 /* A value of current_y < last_visible_y means that we stopped 16172 /* A value of current_y < last_visible_y means that we stopped
@@ -28239,12 +28253,18 @@ The face used for trailing whitespace is `trailing-whitespace'. */);
28239 Vshow_trailing_whitespace = Qnil; 28253 Vshow_trailing_whitespace = Qnil;
28240 28254
28241 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display, 28255 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
28242 doc: /* *Control highlighting of nobreak space and soft hyphen. 28256 doc: /* Control highlighting of non-ASCII space and hyphen chars.
28243A value of t means highlight the character itself (for nobreak space, 28257If the value is t, Emacs highlights non-ASCII chars which have the
28244use face `nobreak-space'). 28258same appearance as an ASCII space or hyphen, using the `nobreak-space'
28245A value of nil means no highlighting. 28259or `escape-glyph' face respectively.
28246Other values mean display the escape glyph followed by an ordinary 28260
28247space or ordinary hyphen. */); 28261U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
28262U+2011 (non-breaking hyphen) are affected.
28263
28264Any other non-nil value means to display these characters as a escape
28265glyph followed by an ordinary space or hyphen.
28266
28267A value of nil means no special handling of these characters. */);
28248 Vnobreak_char_display = Qt; 28268 Vnobreak_char_display = Qt;
28249 28269
28250 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer, 28270 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,