diff options
| author | Paul Eggert | 2011-10-22 23:38:24 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-10-22 23:38:24 -0700 |
| commit | cfc09582247ffef6a46b6249e2fba9136a62d21e (patch) | |
| tree | 50e102f64a2b88c692d9110990abd416c78c32f0 /src | |
| parent | 92c938895c639463681ae1c58a944cae62b70b87 (diff) | |
| parent | 86c606818495d9411fd5d6b1477f9a097eb18020 (diff) | |
| download | emacs-cfc09582247ffef6a46b6249e2fba9136a62d21e.tar.gz emacs-cfc09582247ffef6a46b6249e2fba9136a62d21e.zip | |
Merge from trunk.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 79 | ||||
| -rw-r--r-- | src/bidi.c | 99 | ||||
| -rw-r--r-- | src/dispextern.h | 3 | ||||
| -rw-r--r-- | src/editfns.c | 91 | ||||
| -rw-r--r-- | src/systime.h | 11 | ||||
| -rw-r--r-- | src/xdisp.c | 98 |
6 files changed, 257 insertions, 124 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 7b21a47d59a..34914c96c6c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | 2011-10-17 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2011-10-23 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | Fix integer width and related bugs. | 3 | Fix integer width and related bugs. |
| 4 | * alloc.c (pure_bytes_used_lisp, pure_bytes_used_non_lisp): | 4 | * alloc.c (pure_bytes_used_lisp, pure_bytes_used_non_lisp): |
| @@ -789,6 +789,83 @@ | |||
| 789 | rather than rolling our own approximation. | 789 | rather than rolling our own approximation. |
| 790 | (SCROLL_BAR_VEC_SIZE): Remove; not used. | 790 | (SCROLL_BAR_VEC_SIZE): Remove; not used. |
| 791 | 791 | ||
| 792 | 2011-10-20 Eli Zaretskii <eliz@gnu.org> | ||
| 793 | |||
| 794 | * dispextern.h (struct bidi_it): New member next_en_type. | ||
| 795 | |||
| 796 | * bidi.c (bidi_line_init): Initialize the next_en_type member. | ||
| 797 | (bidi_resolve_explicit_1): When next_en_pos is valid for the | ||
| 798 | current character, check also for next_en_type being WEAK_EN. | ||
| 799 | (bidi_resolve_weak): Don't enter the expensive loop if the current | ||
| 800 | position is before next_en_pos. Record the bidi type of the first | ||
| 801 | non-ET, non-BN character we find, in addition to its position. | ||
| 802 | (bidi_level_of_next_char): Invalidate next_en_type when | ||
| 803 | next_en_pos is over-stepped. | ||
| 804 | |||
| 805 | 2011-10-20 Paul Eggert <eggert@cs.ucla.edu> | ||
| 806 | |||
| 807 | Time zone name fixes for non-ASCII locales (Bug#641, Bug#9794) | ||
| 808 | * editfns.c: Rewrite current-time-zone so that it invokes | ||
| 809 | the equivalent of (format-time-string "%Z") to get the time zone name. | ||
| 810 | This fixes a bug when the time zone name contains characters that | ||
| 811 | need converting from the system time locale to Emacs internal format. | ||
| 812 | This fixes a shortcoming that I introduced in my 1999-10-19 patch: | ||
| 813 | that patch fixed format-time-string to do the conversion, but | ||
| 814 | I forgot to fix current-time-zone. | ||
| 815 | (format_time_string): New function, containing most of | ||
| 816 | what Fformat_time_string used to contain. | ||
| 817 | (Fformat_time_string): Rewrite in terms of format_time_string. | ||
| 818 | This doesn't change this function's behavior. | ||
| 819 | (current-time-zone): Rewrite to use format_time_string. | ||
| 820 | This fixes the bug reported by Michael Schierl in | ||
| 821 | <http://lists.gnu.org/archive/html/emacs-devel/2007-06/msg00334.html>. | ||
| 822 | Jason Rumney's 2007-06-07 change worked around this bug, but | ||
| 823 | didn't fix it. | ||
| 824 | * systime.h (tzname, timezone): Remove no-longer-used declarations. | ||
| 825 | |||
| 826 | 2011-10-19 Eli Zaretskii <eliz@gnu.org> | ||
| 827 | |||
| 828 | * xdisp.c (start_display): If the character at POS is displayed | ||
| 829 | via a display vector, reset IT->current.dpvec_index to zero. | ||
| 830 | (try_window_reusing_current_matrix): If a line ends in a display | ||
| 831 | vector or the next line starts in a display vector, continue | ||
| 832 | redrawing the window even though the character position of | ||
| 833 | start_row was reached. | ||
| 834 | (Bug#9771, part 2) | ||
| 835 | |||
| 836 | 2011-10-18 Chong Yidong <cyd@gnu.org> | ||
| 837 | |||
| 838 | * xdisp.c (get_next_display_element): Handle U+2010 and U+2011 | ||
| 839 | with nobreak-char-display too. | ||
| 840 | |||
| 841 | 2011-10-18 Eli Zaretskii <eliz@gnu.org> | ||
| 842 | |||
| 843 | Fix part 3 of bug#9771. | ||
| 844 | * bidi.c (bidi_line_init): Initialize next_en_pos to zero, not -1. | ||
| 845 | (bidi_resolve_neutral): Don't enter the expensive loop looking for | ||
| 846 | non-neutral characters if the current character is a paragraph | ||
| 847 | separator (a.k.a. Newline). This avoids running the same | ||
| 848 | expensive loop twice, once when we consume the preceding newline | ||
| 849 | and the other time when the line actually needs to be displayed. | ||
| 850 | Avoid the loop when we see neutrals on the base embedding level | ||
| 851 | following a character whose directionality is the same as the | ||
| 852 | paragraph's. This avoids running the expensive loop when a line | ||
| 853 | ends in a long sequence of neutrals, like control characters. | ||
| 854 | Add assertion against STRONG_AL type. Slightly rearrange code | ||
| 855 | that determines the type of a neutral given the first non-neutral | ||
| 856 | that follows it. | ||
| 857 | (bidi_level_of_next_char): Set next_en_pos to zero when | ||
| 858 | invalidating its info. | ||
| 859 | |||
| 860 | 2011-10-17 Eli Zaretskii <eliz@gnu.org> | ||
| 861 | |||
| 862 | * xdisp.c (push_display_prop): Determine whether to record string | ||
| 863 | or buffer position by IT->string, not by IT->method. Allow | ||
| 864 | GET_FROM_DISPLAY_VECTOR as IT->method on entry. (Bug#9771, part 4) | ||
| 865 | (move_it_vertically_backward): Don't look for character position | ||
| 866 | immediately after the newline when in a continuation line. | ||
| 867 | (Bug#9771, part 1) | ||
| 868 | |||
| 792 | 2011-10-15 Martin Rudalics <rudalics@gmx.at> | 869 | 2011-10-15 Martin Rudalics <rudalics@gmx.at> |
| 793 | 870 | ||
| 794 | * window.c (coordinates_in_window): Rewrite and delabelize | 871 | * window.c (coordinates_in_window): Rewrite and delabelize |
diff --git a/src/bidi.c b/src/bidi.c index c6d7db96576..e8f2df89a9e 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -846,7 +846,10 @@ bidi_line_init (struct bidi_it *bidi_it) | |||
| 846 | bidi_it->level_stack[0].override = NEUTRAL_DIR; /* X1 */ | 846 | bidi_it->level_stack[0].override = NEUTRAL_DIR; /* X1 */ |
| 847 | bidi_it->invalid_levels = 0; | 847 | bidi_it->invalid_levels = 0; |
| 848 | bidi_it->invalid_rl_levels = -1; | 848 | bidi_it->invalid_rl_levels = -1; |
| 849 | bidi_it->next_en_pos = -1; | 849 | /* Setting this to zero will force its recomputation the first time |
| 850 | we need it for W5. */ | ||
| 851 | bidi_it->next_en_pos = 0; | ||
| 852 | bidi_it->next_en_type = UNKNOWN_BT; | ||
| 850 | bidi_it->next_for_ws.type = UNKNOWN_BT; | 853 | bidi_it->next_for_ws.type = UNKNOWN_BT; |
| 851 | bidi_set_sor_type (bidi_it, | 854 | bidi_set_sor_type (bidi_it, |
| 852 | (bidi_it->paragraph_dir == R2L ? 1 : 0), | 855 | (bidi_it->paragraph_dir == R2L ? 1 : 0), |
| @@ -1435,7 +1438,8 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1435 | } | 1438 | } |
| 1436 | } | 1439 | } |
| 1437 | 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 */ |
| 1438 | || 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)) | ||
| 1439 | type = WEAK_EN; | 1443 | type = WEAK_EN; |
| 1440 | break; | 1444 | break; |
| 1441 | case LRE: /* X3 */ | 1445 | case LRE: /* X3 */ |
| @@ -1471,7 +1475,8 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1471 | } | 1475 | } |
| 1472 | } | 1476 | } |
| 1473 | 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 */ |
| 1474 | || 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)) | ||
| 1475 | type = WEAK_EN; | 1480 | type = WEAK_EN; |
| 1476 | break; | 1481 | break; |
| 1477 | case PDF: /* X7 */ | 1482 | case PDF: /* X7 */ |
| @@ -1497,7 +1502,8 @@ bidi_resolve_explicit_1 (struct bidi_it *bidi_it) | |||
| 1497 | } | 1502 | } |
| 1498 | } | 1503 | } |
| 1499 | 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 */ |
| 1500 | || 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)) | ||
| 1501 | type = WEAK_EN; | 1507 | type = WEAK_EN; |
| 1502 | break; | 1508 | break; |
| 1503 | default: | 1509 | default: |
| @@ -1729,10 +1735,15 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1729 | 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 */ |
| 1730 | || type == WEAK_BN) /* W5/Retaining */ | 1736 | || type == WEAK_BN) /* W5/Retaining */ |
| 1731 | { | 1737 | { |
| 1732 | 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 */ |
| 1733 | || bidi_it->next_en_pos > bidi_it->charpos) | ||
| 1734 | type = WEAK_EN; | 1739 | type = WEAK_EN; |
| 1735 | else /* 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) | ||
| 1736 | { | 1747 | { |
| 1737 | ptrdiff_t en_pos = bidi_it->charpos + bidi_it->nchars; | 1748 | ptrdiff_t en_pos = bidi_it->charpos + bidi_it->nchars; |
| 1738 | const unsigned char *s = (STRINGP (bidi_it->string.lstring) | 1749 | const unsigned char *s = (STRINGP (bidi_it->string.lstring) |
| @@ -1761,20 +1772,27 @@ bidi_resolve_weak (struct bidi_it *bidi_it) | |||
| 1761 | en_pos = bidi_it->charpos; | 1772 | en_pos = bidi_it->charpos; |
| 1762 | bidi_copy_it (bidi_it, &saved_it); | 1773 | bidi_copy_it (bidi_it, &saved_it); |
| 1763 | } | 1774 | } |
| 1775 | /* Remember this position, to speed up processing of the | ||
| 1776 | next ETs. */ | ||
| 1777 | bidi_it->next_en_pos = en_pos; | ||
| 1764 | if (type_of_next == WEAK_EN) | 1778 | if (type_of_next == WEAK_EN) |
| 1765 | { | 1779 | { |
| 1766 | /* If the last strong character is AL, the EN we've | 1780 | /* If the last strong character is AL, the EN we've |
| 1767 | found will become AN when we get to it (W2). */ | 1781 | found will become AN when we get to it (W2). */ |
| 1768 | if (bidi_it->last_strong.type_after_w1 != STRONG_AL) | 1782 | if (bidi_it->last_strong.type_after_w1 == STRONG_AL) |
| 1769 | { | 1783 | type_of_next = WEAK_AN; |
| 1770 | type = WEAK_EN; | ||
| 1771 | /* Remember this EN position, to speed up processing | ||
| 1772 | of the next ETs. */ | ||
| 1773 | bidi_it->next_en_pos = en_pos; | ||
| 1774 | } | ||
| 1775 | else if (type == WEAK_BN) | 1784 | else if (type == WEAK_BN) |
| 1776 | type = NEUTRAL_ON; /* W6/Retaining */ | 1785 | type = NEUTRAL_ON; /* W6/Retaining */ |
| 1786 | else | ||
| 1787 | type = WEAK_EN; | ||
| 1777 | } | 1788 | } |
| 1789 | else if (type_of_next == NEUTRAL_B) | ||
| 1790 | /* Record the fact that there are no more ENs from | ||
| 1791 | here to the end of paragraph, to avoid entering the | ||
| 1792 | loop above ever again in this paragraph. */ | ||
| 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; | ||
| 1778 | } | 1796 | } |
| 1779 | } | 1797 | } |
| 1780 | } | 1798 | } |
| @@ -1843,13 +1861,45 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 1843 | || type == NEUTRAL_ON)) | 1861 | || type == NEUTRAL_ON)) |
| 1844 | abort (); | 1862 | abort (); |
| 1845 | 1863 | ||
| 1846 | if (bidi_get_category (type) == NEUTRAL | 1864 | if ((type != NEUTRAL_B /* Don't risk entering the long loop below if |
| 1865 | we are already at paragraph end. */ | ||
| 1866 | && bidi_get_category (type) == NEUTRAL) | ||
| 1847 | || (type == WEAK_BN && prev_level == current_level)) | 1867 | || (type == WEAK_BN && prev_level == current_level)) |
| 1848 | { | 1868 | { |
| 1849 | if (bidi_it->next_for_neutral.type != UNKNOWN_BT) | 1869 | if (bidi_it->next_for_neutral.type != UNKNOWN_BT) |
| 1850 | type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type, | 1870 | type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type, |
| 1851 | bidi_it->next_for_neutral.type, | 1871 | bidi_it->next_for_neutral.type, |
| 1852 | current_level); | 1872 | current_level); |
| 1873 | /* The next two "else if" clauses are shortcuts for the | ||
| 1874 | important special case when we have a long sequence of | ||
| 1875 | neutral or WEAK_BN characters, such as whitespace or nulls or | ||
| 1876 | other control characters, on the base embedding level of the | ||
| 1877 | paragraph, and that sequence goes all the way to the end of | ||
| 1878 | the paragraph and follows a character whose resolved | ||
| 1879 | directionality is identical to the base embedding level. | ||
| 1880 | (This is what happens in a buffer with plain L2R text that | ||
| 1881 | happens to include long sequences of control characters.) By | ||
| 1882 | virtue of N1, the result of examining this long sequence will | ||
| 1883 | always be either STRONG_L or STRONG_R, depending on the base | ||
| 1884 | embedding level. So we use this fact directly instead of | ||
| 1885 | entering the expensive loop in the "else" clause. */ | ||
| 1886 | else if (current_level == 0 | ||
| 1887 | && bidi_it->prev_for_neutral.type == STRONG_L | ||
| 1888 | && !bidi_explicit_dir_char (bidi_it->ch)) | ||
| 1889 | type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type, | ||
| 1890 | STRONG_L, current_level); | ||
| 1891 | else if (/* current level is 1 */ | ||
| 1892 | current_level == 1 | ||
| 1893 | /* base embedding level is also 1 */ | ||
| 1894 | && bidi_it->level_stack[0].level == 1 | ||
| 1895 | /* previous character is one of those considered R for | ||
| 1896 | the purposes of W5 */ | ||
| 1897 | && (bidi_it->prev_for_neutral.type == STRONG_R | ||
| 1898 | || bidi_it->prev_for_neutral.type == WEAK_EN | ||
| 1899 | || bidi_it->prev_for_neutral.type == WEAK_AN) | ||
| 1900 | && !bidi_explicit_dir_char (bidi_it->ch)) | ||
| 1901 | type = bidi_resolve_neutral_1 (bidi_it->prev_for_neutral.type, | ||
| 1902 | STRONG_R, current_level); | ||
| 1853 | else | 1903 | else |
| 1854 | { | 1904 | { |
| 1855 | /* Arrrgh!! The UAX#9 algorithm is too deeply entrenched in | 1905 | /* Arrrgh!! The UAX#9 algorithm is too deeply entrenched in |
| @@ -1900,6 +1950,9 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 1900 | case STRONG_L: | 1950 | case STRONG_L: |
| 1901 | case STRONG_R: | 1951 | case STRONG_R: |
| 1902 | case STRONG_AL: | 1952 | case STRONG_AL: |
| 1953 | /* Actually, STRONG_AL cannot happen here, because | ||
| 1954 | bidi_resolve_weak converts it to STRONG_R, per W3. */ | ||
| 1955 | xassert (type != STRONG_AL); | ||
| 1903 | next_type = type; | 1956 | next_type = type; |
| 1904 | break; | 1957 | break; |
| 1905 | case WEAK_EN: | 1958 | case WEAK_EN: |
| @@ -1907,7 +1960,6 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 1907 | /* N1: ``European and Arabic numbers are treated as | 1960 | /* N1: ``European and Arabic numbers are treated as |
| 1908 | though they were R.'' */ | 1961 | though they were R.'' */ |
| 1909 | next_type = STRONG_R; | 1962 | next_type = STRONG_R; |
| 1910 | saved_it.next_for_neutral.type = STRONG_R; | ||
| 1911 | break; | 1963 | break; |
| 1912 | case WEAK_BN: | 1964 | case WEAK_BN: |
| 1913 | if (!bidi_explicit_dir_char (bidi_it->ch)) | 1965 | if (!bidi_explicit_dir_char (bidi_it->ch)) |
| @@ -1920,11 +1972,7 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 1920 | member. */ | 1972 | member. */ |
| 1921 | if (saved_it.type != WEAK_BN | 1973 | if (saved_it.type != WEAK_BN |
| 1922 | || bidi_get_category (bidi_it->prev.type_after_w1) == NEUTRAL) | 1974 | || bidi_get_category (bidi_it->prev.type_after_w1) == NEUTRAL) |
| 1923 | { | 1975 | next_type = bidi_it->prev_for_neutral.type; |
| 1924 | next_type = bidi_it->prev_for_neutral.type; | ||
| 1925 | saved_it.next_for_neutral.type = next_type; | ||
| 1926 | bidi_check_type (next_type); | ||
| 1927 | } | ||
| 1928 | else | 1976 | else |
| 1929 | { | 1977 | { |
| 1930 | /* This is a BN which does not adjoin neutrals. | 1978 | /* This is a BN which does not adjoin neutrals. |
| @@ -1938,7 +1986,9 @@ bidi_resolve_neutral (struct bidi_it *bidi_it) | |||
| 1938 | } | 1986 | } |
| 1939 | type = bidi_resolve_neutral_1 (saved_it.prev_for_neutral.type, | 1987 | type = bidi_resolve_neutral_1 (saved_it.prev_for_neutral.type, |
| 1940 | next_type, current_level); | 1988 | next_type, current_level); |
| 1989 | saved_it.next_for_neutral.type = next_type; | ||
| 1941 | saved_it.type = type; | 1990 | saved_it.type = type; |
| 1991 | bidi_check_type (next_type); | ||
| 1942 | bidi_check_type (type); | 1992 | bidi_check_type (type); |
| 1943 | bidi_copy_it (bidi_it, &saved_it); | 1993 | bidi_copy_it (bidi_it, &saved_it); |
| 1944 | } | 1994 | } |
| @@ -2014,7 +2064,10 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2014 | bidi_it->next_for_neutral.type = UNKNOWN_BT; | 2064 | bidi_it->next_for_neutral.type = UNKNOWN_BT; |
| 2015 | if (bidi_it->next_en_pos >= 0 | 2065 | if (bidi_it->next_en_pos >= 0 |
| 2016 | && bidi_it->charpos >= bidi_it->next_en_pos) | 2066 | && bidi_it->charpos >= bidi_it->next_en_pos) |
| 2017 | bidi_it->next_en_pos = -1; | 2067 | { |
| 2068 | bidi_it->next_en_pos = 0; | ||
| 2069 | bidi_it->next_en_type = UNKNOWN_BT; | ||
| 2070 | } | ||
| 2018 | if (bidi_it->next_for_ws.type != UNKNOWN_BT | 2071 | if (bidi_it->next_for_ws.type != UNKNOWN_BT |
| 2019 | && bidi_it->charpos >= bidi_it->next_for_ws.charpos) | 2072 | && bidi_it->charpos >= bidi_it->next_for_ws.charpos) |
| 2020 | bidi_it->next_for_ws.type = UNKNOWN_BT; | 2073 | bidi_it->next_for_ws.type = UNKNOWN_BT; |
| @@ -2140,7 +2193,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it) | |||
| 2140 | } | 2193 | } |
| 2141 | 2194 | ||
| 2142 | /* Resolve implicit levels, with a twist: PDFs get the embedding | 2195 | /* Resolve implicit levels, with a twist: PDFs get the embedding |
| 2143 | level of the enbedding they terminate. See below for the | 2196 | level of the embedding they terminate. See below for the |
| 2144 | reason. */ | 2197 | reason. */ |
| 2145 | if (bidi_it->orig_type == PDF | 2198 | if (bidi_it->orig_type == PDF |
| 2146 | /* 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 dfef2884297..5f2c844b58d 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -1856,7 +1856,8 @@ struct bidi_it { | |||
| 1856 | struct bidi_saved_info next_for_neutral; /* surrounding characters for... */ | 1856 | struct bidi_saved_info next_for_neutral; /* surrounding characters for... */ |
| 1857 | struct bidi_saved_info prev_for_neutral; /* ...resolving neutrals */ | 1857 | struct bidi_saved_info prev_for_neutral; /* ...resolving neutrals */ |
| 1858 | struct bidi_saved_info next_for_ws; /* character after sequence of ws */ | 1858 | struct bidi_saved_info next_for_ws; /* character after sequence of ws */ |
| 1859 | ptrdiff_t next_en_pos; /* position of next EN char for ET */ | 1859 | ptrdiff_t next_en_pos; /* pos. of next char for determining ET type */ |
| 1860 | bidi_type_t next_en_type; /* type of char at next_en_pos */ | ||
| 1860 | ptrdiff_t ignore_bn_limit; /* position until which to ignore BNs */ | 1861 | ptrdiff_t ignore_bn_limit; /* position until which to ignore BNs */ |
| 1861 | bidi_dir_t sor; /* direction of start-of-run in effect */ | 1862 | bidi_dir_t sor; /* direction of start-of-run in effect */ |
| 1862 | int scan_dir; /* direction of text scan, 1: forw, -1: back */ | 1863 | int scan_dir; /* direction of text scan, 1: forw, -1: back */ |
diff --git a/src/editfns.c b/src/editfns.c index b376c3a7c51..16e552afe1d 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 | ||
| 87 | static void time_overflow (void) NO_RETURN; | 87 | static void time_overflow (void) NO_RETURN; |
| 88 | static Lisp_Object format_time_string (char const *, ptrdiff_t, Lisp_Object, | ||
| 89 | int, time_t *, struct tm **); | ||
| 88 | static int tm_diff (struct tm *, struct tm *); | 90 | static int tm_diff (struct tm *, struct tm *); |
| 89 | static void update_buffer_properties (ptrdiff_t, ptrdiff_t); | 91 | static void update_buffer_properties (ptrdiff_t, ptrdiff_t); |
| 90 | 92 | ||
| @@ -1687,32 +1689,40 @@ For example, to produce full ISO 8601 format, use "%Y-%m-%dT%T%z". | |||
| 1687 | usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */) | 1689 | usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */) |
| 1688 | (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal) | 1690 | (Lisp_Object format_string, Lisp_Object timeval, Lisp_Object universal) |
| 1689 | { | 1691 | { |
| 1690 | time_t value; | 1692 | time_t t; |
| 1693 | struct tm *tm; | ||
| 1694 | |||
| 1695 | CHECK_STRING (format_string); | ||
| 1696 | format_string = code_convert_string_norecord (format_string, | ||
| 1697 | Vlocale_coding_system, 1); | ||
| 1698 | return format_time_string (SSDATA (format_string), SBYTES (format_string), | ||
| 1699 | timeval, ! NILP (universal), &t, &tm); | ||
| 1700 | } | ||
| 1701 | |||
| 1702 | static Lisp_Object | ||
| 1703 | format_time_string (char const *format, ptrdiff_t formatlen, | ||
| 1704 | Lisp_Object timeval, int ut, time_t *tval, struct tm **tmp) | ||
| 1705 | { | ||
| 1691 | ptrdiff_t size; | 1706 | ptrdiff_t size; |
| 1692 | int usec; | 1707 | int usec; |
| 1693 | int ns; | 1708 | int ns; |
| 1694 | struct tm *tm; | 1709 | struct tm *tm; |
| 1695 | int ut = ! NILP (universal); | ||
| 1696 | |||
| 1697 | CHECK_STRING (format_string); | ||
| 1698 | 1710 | ||
| 1699 | if (! lisp_time_argument (timeval, &value, &usec)) | 1711 | if (! lisp_time_argument (timeval, tval, &usec)) |
| 1700 | error ("Invalid time specification"); | 1712 | error ("Invalid time specification"); |
| 1701 | ns = usec * 1000; | 1713 | ns = usec * 1000; |
| 1702 | 1714 | ||
| 1703 | format_string = code_convert_string_norecord (format_string, | ||
| 1704 | Vlocale_coding_system, 1); | ||
| 1705 | |||
| 1706 | /* This is probably enough. */ | 1715 | /* This is probably enough. */ |
| 1707 | size = SBYTES (format_string); | 1716 | size = formatlen; |
| 1708 | if (size <= (STRING_BYTES_BOUND - 50) / 6) | 1717 | if (size <= (STRING_BYTES_BOUND - 50) / 6) |
| 1709 | size = size * 6 + 50; | 1718 | size = size * 6 + 50; |
| 1710 | 1719 | ||
| 1711 | BLOCK_INPUT; | 1720 | BLOCK_INPUT; |
| 1712 | tm = ut ? gmtime (&value) : localtime (&value); | 1721 | tm = ut ? gmtime (tval) : localtime (tval); |
| 1713 | UNBLOCK_INPUT; | 1722 | UNBLOCK_INPUT; |
| 1714 | if (! tm) | 1723 | if (! tm) |
| 1715 | time_overflow (); | 1724 | time_overflow (); |
| 1725 | *tmp = tm; | ||
| 1716 | 1726 | ||
| 1717 | synchronize_system_time_locale (); | 1727 | synchronize_system_time_locale (); |
| 1718 | 1728 | ||
| @@ -1723,9 +1733,7 @@ usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */) | |||
| 1723 | 1733 | ||
| 1724 | buf[0] = '\1'; | 1734 | buf[0] = '\1'; |
| 1725 | BLOCK_INPUT; | 1735 | BLOCK_INPUT; |
| 1726 | result = emacs_nmemftime (buf, size, SSDATA (format_string), | 1736 | result = emacs_nmemftime (buf, size, format, formatlen, tm, ut, ns); |
| 1727 | SBYTES (format_string), | ||
| 1728 | tm, ut, ns); | ||
| 1729 | UNBLOCK_INPUT; | 1737 | UNBLOCK_INPUT; |
| 1730 | if ((result > 0 && result < size) || (result == 0 && buf[0] == '\0')) | 1738 | if ((result > 0 && result < size) || (result == 0 && buf[0] == '\0')) |
| 1731 | return code_convert_string_norecord (make_unibyte_string (buf, result), | 1739 | return code_convert_string_norecord (make_unibyte_string (buf, result), |
| @@ -1733,9 +1741,7 @@ usage: (format-time-string FORMAT-STRING &optional TIME UNIVERSAL) */) | |||
| 1733 | 1741 | ||
| 1734 | /* If buffer was too small, make it bigger and try again. */ | 1742 | /* If buffer was too small, make it bigger and try again. */ |
| 1735 | BLOCK_INPUT; | 1743 | BLOCK_INPUT; |
| 1736 | result = emacs_nmemftime (NULL, (size_t) -1, | 1744 | result = emacs_nmemftime (NULL, (size_t) -1, format, formatlen, |
| 1737 | SSDATA (format_string), | ||
| 1738 | SBYTES (format_string), | ||
| 1739 | tm, ut, ns); | 1745 | tm, ut, ns); |
| 1740 | UNBLOCK_INPUT; | 1746 | UNBLOCK_INPUT; |
| 1741 | if (STRING_BYTES_BOUND <= result) | 1747 | if (STRING_BYTES_BOUND <= result) |
| @@ -1983,51 +1989,34 @@ the data it can't find. */) | |||
| 1983 | { | 1989 | { |
| 1984 | time_t value; | 1990 | time_t value; |
| 1985 | struct tm *t; | 1991 | struct tm *t; |
| 1986 | struct tm gmt; | 1992 | struct tm localtm; |
| 1987 | 1993 | struct tm *localt; | |
| 1988 | if (!lisp_time_argument (specified_time, &value, NULL)) | 1994 | Lisp_Object zone_offset, zone_name; |
| 1989 | t = NULL; | 1995 | |
| 1990 | else | 1996 | zone_offset = Qnil; |
| 1991 | { | 1997 | zone_name = format_time_string ("%Z", sizeof "%Z" - 1, specified_time, |
| 1992 | BLOCK_INPUT; | 1998 | 0, &value, &localt); |
| 1993 | t = gmtime (&value); | 1999 | localtm = *localt; |
| 1994 | if (t) | 2000 | BLOCK_INPUT; |
| 1995 | { | 2001 | t = gmtime (&value); |
| 1996 | gmt = *t; | 2002 | UNBLOCK_INPUT; |
| 1997 | t = localtime (&value); | ||
| 1998 | } | ||
| 1999 | UNBLOCK_INPUT; | ||
| 2000 | } | ||
| 2001 | 2003 | ||
| 2002 | if (t) | 2004 | if (t) |
| 2003 | { | 2005 | { |
| 2004 | int offset = tm_diff (t, &gmt); | 2006 | int offset = tm_diff (&localtm, t); |
| 2005 | char *s = 0; | 2007 | zone_offset = make_number (offset); |
| 2006 | char buf[sizeof "+00" + INT_STRLEN_BOUND (int)]; | 2008 | if (SCHARS (zone_name) == 0) |
| 2007 | |||
| 2008 | #ifdef HAVE_TM_ZONE | ||
| 2009 | if (t->tm_zone) | ||
| 2010 | s = (char *)t->tm_zone; | ||
| 2011 | #else /* not HAVE_TM_ZONE */ | ||
| 2012 | #ifdef HAVE_TZNAME | ||
| 2013 | if (t->tm_isdst == 0 || t->tm_isdst == 1) | ||
| 2014 | s = tzname[t->tm_isdst]; | ||
| 2015 | #endif | ||
| 2016 | #endif /* not HAVE_TM_ZONE */ | ||
| 2017 | |||
| 2018 | if (!s) | ||
| 2019 | { | 2009 | { |
| 2020 | /* No local time zone name is available; use "+-NNNN" instead. */ | 2010 | /* No local time zone name is available; use "+-NNNN" instead. */ |
| 2021 | int m = offset / 60; | 2011 | int m = offset / 60; |
| 2022 | int am = offset < 0 ? - m : m; | 2012 | int am = offset < 0 ? - m : m; |
| 2013 | char buf[sizeof "+00" + INT_STRLEN_BOUND (int)]; | ||
| 2023 | sprintf (buf, "%c%02d%02d", (offset < 0 ? '-' : '+'), am/60, am%60); | 2014 | sprintf (buf, "%c%02d%02d", (offset < 0 ? '-' : '+'), am/60, am%60); |
| 2024 | s = buf; | 2015 | zone_name = build_string (buf); |
| 2025 | } | 2016 | } |
| 2026 | |||
| 2027 | return Fcons (make_number (offset), Fcons (build_string (s), Qnil)); | ||
| 2028 | } | 2017 | } |
| 2029 | else | 2018 | |
| 2030 | return Fmake_list (make_number (2), Qnil); | 2019 | return list2 (zone_offset, zone_name); |
| 2031 | } | 2020 | } |
| 2032 | 2021 | ||
| 2033 | /* This holds the value of `environ' produced by the previous | 2022 | /* 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. */ | ||
| 43 | extern 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 | ||
| 49 | extern 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 a264da3892a..cb68969ae2d 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -2854,6 +2854,13 @@ start_display (struct it *it, struct window *w, struct text_pos pos) | |||
| 2854 | 2854 | ||
| 2855 | it->continuation_lines_width += it->current_x; | 2855 | it->continuation_lines_width += it->current_x; |
| 2856 | } | 2856 | } |
| 2857 | /* If the character at POS is displayed via a display | ||
| 2858 | vector, move_it_to above stops at the final glyph of | ||
| 2859 | IT->dpvec. To make the caller redisplay that character | ||
| 2860 | again (a.k.a. start at POS), we need to reset the | ||
| 2861 | dpvec_index to the beginning of IT->dpvec. */ | ||
| 2862 | else if (it->current.dpvec_index >= 0) | ||
| 2863 | it->current.dpvec_index = 0; | ||
| 2857 | 2864 | ||
| 2858 | /* We're starting a new display line, not affected by the | 2865 | /* We're starting a new display line, not affected by the |
| 2859 | height of the continued line, so clear the appropriate | 2866 | height of the continued line, so clear the appropriate |
| @@ -6379,8 +6386,8 @@ get_next_display_element (struct it *it) | |||
| 6379 | { | 6386 | { |
| 6380 | Lisp_Object dv; | 6387 | Lisp_Object dv; |
| 6381 | struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte); | 6388 | struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte); |
| 6382 | enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen } | 6389 | int nonascii_space_p = 0; |
| 6383 | nbsp_or_shy = char_is_other; | 6390 | int nonascii_hyphen_p = 0; |
| 6384 | int c = it->c; /* This is the character to display. */ | 6391 | int c = it->c; /* This is the character to display. */ |
| 6385 | 6392 | ||
| 6386 | if (! it->multibyte_p && ! ASCII_CHAR_P (c)) | 6393 | if (! it->multibyte_p && ! ASCII_CHAR_P (c)) |
| @@ -6432,10 +6439,15 @@ get_next_display_element (struct it *it) | |||
| 6432 | goto get_next; | 6439 | goto get_next; |
| 6433 | } | 6440 | } |
| 6434 | 6441 | ||
| 6442 | /* If `nobreak-char-display' is non-nil, we display | ||
| 6443 | non-ASCII spaces and hyphens specially. */ | ||
| 6435 | if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display)) | 6444 | if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display)) |
| 6436 | nbsp_or_shy = (c == 0xA0 ? char_is_nbsp | 6445 | { |
| 6437 | : c == 0xAD ? char_is_soft_hyphen | 6446 | if (c == 0xA0) |
| 6438 | : char_is_other); | 6447 | nonascii_space_p = 1; |
| 6448 | else if (c == 0xAD || c == 0x2010 || c == 0x2011) | ||
| 6449 | nonascii_hyphen_p = 1; | ||
| 6450 | } | ||
| 6439 | 6451 | ||
| 6440 | /* Translate control characters into `\003' or `^C' form. | 6452 | /* Translate control characters into `\003' or `^C' form. |
| 6441 | Control characters coming from a display table entry are | 6453 | Control characters coming from a display table entry are |
| @@ -6443,7 +6455,8 @@ get_next_display_element (struct it *it) | |||
| 6443 | the translation. This could easily be changed but I | 6455 | the translation. This could easily be changed but I |
| 6444 | don't believe that it is worth doing. | 6456 | don't believe that it is worth doing. |
| 6445 | 6457 | ||
| 6446 | NBSP and SOFT-HYPEN are property translated too. | 6458 | The characters handled by `nobreak-char-display' must be |
| 6459 | translated too. | ||
| 6447 | 6460 | ||
| 6448 | Non-printable characters and raw-byte characters are also | 6461 | Non-printable characters and raw-byte characters are also |
| 6449 | translated to octal form. */ | 6462 | translated to octal form. */ |
| @@ -6454,14 +6467,15 @@ get_next_display_element (struct it *it) | |||
| 6454 | && it->glyph_row | 6467 | && it->glyph_row |
| 6455 | && (it->glyph_row->mode_line_p || it->avoid_cursor_p)) | 6468 | && (it->glyph_row->mode_line_p || it->avoid_cursor_p)) |
| 6456 | || (c != '\n' && c != '\t')) | 6469 | || (c != '\n' && c != '\t')) |
| 6457 | : (nbsp_or_shy | 6470 | : (nonascii_space_p |
| 6471 | || nonascii_hyphen_p | ||
| 6458 | || CHAR_BYTE8_P (c) | 6472 | || CHAR_BYTE8_P (c) |
| 6459 | || ! CHAR_PRINTABLE_P (c)))) | 6473 | || ! CHAR_PRINTABLE_P (c)))) |
| 6460 | { | 6474 | { |
| 6461 | /* C is a control character, NBSP, SOFT-HYPEN, raw-byte, | 6475 | /* C is a control character, non-ASCII space/hyphen, |
| 6462 | or a non-printable character which must be displayed | 6476 | raw-byte, or a non-printable character which must be |
| 6463 | either as '\003' or as `^C' where the '\\' and '^' | 6477 | displayed either as '\003' or as `^C' where the '\\' |
| 6464 | can be defined in the display table. Fill | 6478 | and '^' can be defined in the display table. Fill |
| 6465 | IT->ctl_chars with glyphs for what we have to | 6479 | IT->ctl_chars with glyphs for what we have to |
| 6466 | display. Then, set IT->dpvec to these glyphs. */ | 6480 | display. Then, set IT->dpvec to these glyphs. */ |
| 6467 | Lisp_Object gc; | 6481 | Lisp_Object gc; |
| @@ -6509,17 +6523,14 @@ get_next_display_element (struct it *it) | |||
| 6509 | goto display_control; | 6523 | goto display_control; |
| 6510 | } | 6524 | } |
| 6511 | 6525 | ||
| 6512 | /* Handle non-break space in the mode where it only gets | 6526 | /* Handle non-ascii space in the mode where it only gets |
| 6513 | highlighting. */ | 6527 | highlighting. */ |
| 6514 | 6528 | ||
| 6515 | if (EQ (Vnobreak_char_display, Qt) | 6529 | if (nonascii_space_p && EQ (Vnobreak_char_display, Qt)) |
| 6516 | && nbsp_or_shy == char_is_nbsp) | ||
| 6517 | { | 6530 | { |
| 6518 | /* Merge the no-break-space face into the current face. */ | 6531 | /* Merge `nobreak-space' into the current face. */ |
| 6519 | face_id = merge_faces (it->f, Qnobreak_space, 0, | 6532 | face_id = merge_faces (it->f, Qnobreak_space, 0, |
| 6520 | it->face_id); | 6533 | it->face_id); |
| 6521 | |||
| 6522 | c = ' '; | ||
| 6523 | XSETINT (it->ctl_chars[0], ' '); | 6534 | XSETINT (it->ctl_chars[0], ' '); |
| 6524 | ctl_len = 1; | 6535 | ctl_len = 1; |
| 6525 | goto display_control; | 6536 | goto display_control; |
| @@ -6558,25 +6569,21 @@ get_next_display_element (struct it *it) | |||
| 6558 | last_escape_glyph_merged_face_id = face_id; | 6569 | last_escape_glyph_merged_face_id = face_id; |
| 6559 | } | 6570 | } |
| 6560 | 6571 | ||
| 6561 | /* Handle soft hyphens in the mode where they only get | 6572 | /* Draw non-ASCII hyphen with just highlighting: */ |
| 6562 | highlighting. */ | ||
| 6563 | 6573 | ||
| 6564 | if (EQ (Vnobreak_char_display, Qt) | 6574 | if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt)) |
| 6565 | && nbsp_or_shy == char_is_soft_hyphen) | ||
| 6566 | { | 6575 | { |
| 6567 | XSETINT (it->ctl_chars[0], '-'); | 6576 | XSETINT (it->ctl_chars[0], '-'); |
| 6568 | ctl_len = 1; | 6577 | ctl_len = 1; |
| 6569 | goto display_control; | 6578 | goto display_control; |
| 6570 | } | 6579 | } |
| 6571 | 6580 | ||
| 6572 | /* Handle non-break space and soft hyphen | 6581 | /* Draw non-ASCII space/hyphen with escape glyph: */ |
| 6573 | with the escape glyph. */ | ||
| 6574 | 6582 | ||
| 6575 | if (nbsp_or_shy) | 6583 | if (nonascii_space_p || nonascii_hyphen_p) |
| 6576 | { | 6584 | { |
| 6577 | XSETINT (it->ctl_chars[0], escape_glyph); | 6585 | XSETINT (it->ctl_chars[0], escape_glyph); |
| 6578 | c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-'); | 6586 | XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-'); |
| 6579 | XSETINT (it->ctl_chars[1], c); | ||
| 6580 | ctl_len = 2; | 6587 | ctl_len = 2; |
| 6581 | goto display_control; | 6588 | goto display_control; |
| 6582 | } | 6589 | } |
| @@ -8774,7 +8781,10 @@ move_it_vertically_backward (struct it *it, int dy) | |||
| 8774 | reordering. We want to get to the character position | 8781 | reordering. We want to get to the character position |
| 8775 | that is immediately after the newline of the previous | 8782 | that is immediately after the newline of the previous |
| 8776 | line. */ | 8783 | line. */ |
| 8777 | if (it->bidi_p && IT_CHARPOS (*it) > BEGV | 8784 | if (it->bidi_p |
| 8785 | && !it->continuation_lines_width | ||
| 8786 | && !STRINGP (it->string) | ||
| 8787 | && IT_CHARPOS (*it) > BEGV | ||
| 8778 | && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n') | 8788 | && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n') |
| 8779 | { | 8789 | { |
| 8780 | ptrdiff_t nl_pos = | 8790 | ptrdiff_t nl_pos = |
| @@ -16075,13 +16085,20 @@ try_window_reusing_current_matrix (struct window *w) | |||
| 16075 | 16085 | ||
| 16076 | start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix); | 16086 | start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix); |
| 16077 | } | 16087 | } |
| 16078 | /* If we have reached alignment, | 16088 | /* If we have reached alignment, we can copy the rest of the |
| 16079 | we can copy the rest of the rows. */ | 16089 | rows. */ |
| 16080 | if (IT_CHARPOS (it) == CHARPOS (start)) | 16090 | if (IT_CHARPOS (it) == CHARPOS (start) |
| 16091 | /* Don't accept "alignment" inside a display vector, | ||
| 16092 | since start_row could have started in the middle of | ||
| 16093 | that same display vector (thus their character | ||
| 16094 | positions match), and we have no way of telling if | ||
| 16095 | that is the case. */ | ||
| 16096 | && it.current.dpvec_index < 0) | ||
| 16081 | break; | 16097 | break; |
| 16082 | 16098 | ||
| 16083 | if (display_line (&it)) | 16099 | if (display_line (&it)) |
| 16084 | last_text_row = it.glyph_row - 1; | 16100 | last_text_row = it.glyph_row - 1; |
| 16101 | |||
| 16085 | } | 16102 | } |
| 16086 | 16103 | ||
| 16087 | /* A value of current_y < last_visible_y means that we stopped | 16104 | /* A value of current_y < last_visible_y means that we stopped |
| @@ -18434,9 +18451,10 @@ static int | |||
| 18434 | push_display_prop (struct it *it, Lisp_Object prop) | 18451 | push_display_prop (struct it *it, Lisp_Object prop) |
| 18435 | { | 18452 | { |
| 18436 | struct text_pos pos = | 18453 | struct text_pos pos = |
| 18437 | (it->method == GET_FROM_STRING) ? it->current.string_pos : it->current.pos; | 18454 | STRINGP (it->string) ? it->current.string_pos : it->current.pos; |
| 18438 | 18455 | ||
| 18439 | xassert (it->method == GET_FROM_BUFFER | 18456 | xassert (it->method == GET_FROM_BUFFER |
| 18457 | || it->method == GET_FROM_DISPLAY_VECTOR | ||
| 18440 | || it->method == GET_FROM_STRING); | 18458 | || it->method == GET_FROM_STRING); |
| 18441 | 18459 | ||
| 18442 | /* We need to save the current buffer/string position, so it will be | 18460 | /* We need to save the current buffer/string position, so it will be |
| @@ -28004,12 +28022,18 @@ The face used for trailing whitespace is `trailing-whitespace'. */); | |||
| 28004 | Vshow_trailing_whitespace = Qnil; | 28022 | Vshow_trailing_whitespace = Qnil; |
| 28005 | 28023 | ||
| 28006 | DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display, | 28024 | DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display, |
| 28007 | doc: /* *Control highlighting of nobreak space and soft hyphen. | 28025 | doc: /* Control highlighting of non-ASCII space and hyphen chars. |
| 28008 | A value of t means highlight the character itself (for nobreak space, | 28026 | If the value is t, Emacs highlights non-ASCII chars which have the |
| 28009 | use face `nobreak-space'). | 28027 | same appearance as an ASCII space or hyphen, using the `nobreak-space' |
| 28010 | A value of nil means no highlighting. | 28028 | or `escape-glyph' face respectively. |
| 28011 | Other values mean display the escape glyph followed by an ordinary | 28029 | |
| 28012 | space or ordinary hyphen. */); | 28030 | U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and |
| 28031 | U+2011 (non-breaking hyphen) are affected. | ||
| 28032 | |||
| 28033 | Any other non-nil value means to display these characters as a escape | ||
| 28034 | glyph followed by an ordinary space or hyphen. | ||
| 28035 | |||
| 28036 | A value of nil means no special handling of these characters. */); | ||
| 28013 | Vnobreak_char_display = Qt; | 28037 | Vnobreak_char_display = Qt; |
| 28014 | 28038 | ||
| 28015 | DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer, | 28039 | DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer, |