diff options
| author | Paul Eggert | 2015-05-28 00:06:13 -0700 |
|---|---|---|
| committer | Paul Eggert | 2015-05-28 00:22:01 -0700 |
| commit | 11b2744f48fc03f1511de1152ad49807557c6f85 (patch) | |
| tree | 319aded310f155b109149157f6c075138205fbe5 /src | |
| parent | 2363d498fb99bda0b5030c8c1af2925209bb60e5 (diff) | |
| download | emacs-11b2744f48fc03f1511de1152ad49807557c6f85.tar.gz emacs-11b2744f48fc03f1511de1152ad49807557c6f85.zip | |
substitute-command-keys now curves quotes
So, for example, it turns "`abc'" into "‘abc’" (Bug#20385).
* doc/lispref/help.texi (Keys in Documentation):
* etc/NEWS: Document this.
* src/doc.c (Fsubstitute_command_keys): Implement it.
Diffstat (limited to 'src')
| -rw-r--r-- | src/doc.c | 39 |
1 files changed, 33 insertions, 6 deletions
| @@ -693,15 +693,21 @@ summary). | |||
| 693 | 693 | ||
| 694 | Each substring of the form \\=\\<MAPVAR> specifies the use of MAPVAR | 694 | Each substring of the form \\=\\<MAPVAR> specifies the use of MAPVAR |
| 695 | as the keymap for future \\=\\[COMMAND] substrings. | 695 | as the keymap for future \\=\\[COMMAND] substrings. |
| 696 | \\=\\= quotes the following character and is discarded; | 696 | |
| 697 | thus, \\=\\=\\=\\= puts \\=\\= into the output, and \\=\\=\\=\\[ puts \\=\\[ into the output. | 697 | Each \\=` is replaced by ‘. Each ' preceded by \\=` and without |
| 698 | intervening ' is replaced by ’. | ||
| 699 | |||
| 700 | \\=\\= quotes the following character and is discarded; thus, | ||
| 701 | \\=\\=\\=\\= puts \\=\\= into the output, \\=\\=\\=\\[ puts \\=\\[ into the output, and | ||
| 702 | \\=\\=\\=` puts \\=` into the output. | ||
| 698 | 703 | ||
| 699 | Return the original STRING if no substitutions are made. | 704 | Return the original STRING if no substitutions are made. |
| 700 | Otherwise, return a new string. */) | 705 | Otherwise, return a new string. */) |
| 701 | (Lisp_Object string) | 706 | (Lisp_Object string) |
| 702 | { | 707 | { |
| 703 | char *buf; | 708 | char *buf; |
| 704 | bool changed = 0; | 709 | bool changed = false; |
| 710 | bool in_quote = false; | ||
| 705 | unsigned char *strp; | 711 | unsigned char *strp; |
| 706 | char *bufp; | 712 | char *bufp; |
| 707 | ptrdiff_t idx; | 713 | ptrdiff_t idx; |
| @@ -734,6 +740,12 @@ Otherwise, return a new string. */) | |||
| 734 | keymap = Voverriding_local_map; | 740 | keymap = Voverriding_local_map; |
| 735 | 741 | ||
| 736 | bsize = SBYTES (string); | 742 | bsize = SBYTES (string); |
| 743 | |||
| 744 | /* Add some room for expansion due to quote replacement. */ | ||
| 745 | enum { EXTRA_ROOM = 20 }; | ||
| 746 | if (bsize <= STRING_BYTES_BOUND - EXTRA_ROOM) | ||
| 747 | bsize += EXTRA_ROOM; | ||
| 748 | |||
| 737 | bufp = buf = xmalloc (bsize); | 749 | bufp = buf = xmalloc (bsize); |
| 738 | 750 | ||
| 739 | strp = SDATA (string); | 751 | strp = SDATA (string); |
| @@ -743,7 +755,7 @@ Otherwise, return a new string. */) | |||
| 743 | { | 755 | { |
| 744 | /* \= quotes the next character; | 756 | /* \= quotes the next character; |
| 745 | thus, to put in \[ without its special meaning, use \=\[. */ | 757 | thus, to put in \[ without its special meaning, use \=\[. */ |
| 746 | changed = 1; | 758 | changed = true; |
| 747 | strp += 2; | 759 | strp += 2; |
| 748 | if (multibyte) | 760 | if (multibyte) |
| 749 | { | 761 | { |
| @@ -766,7 +778,6 @@ Otherwise, return a new string. */) | |||
| 766 | ptrdiff_t start_idx; | 778 | ptrdiff_t start_idx; |
| 767 | bool follow_remap = 1; | 779 | bool follow_remap = 1; |
| 768 | 780 | ||
| 769 | changed = 1; | ||
| 770 | strp += 2; /* skip \[ */ | 781 | strp += 2; /* skip \[ */ |
| 771 | start = strp; | 782 | start = strp; |
| 772 | start_idx = start - SDATA (string); | 783 | start_idx = start - SDATA (string); |
| @@ -833,7 +844,6 @@ Otherwise, return a new string. */) | |||
| 833 | Lisp_Object earlier_maps; | 844 | Lisp_Object earlier_maps; |
| 834 | ptrdiff_t count = SPECPDL_INDEX (); | 845 | ptrdiff_t count = SPECPDL_INDEX (); |
| 835 | 846 | ||
| 836 | changed = 1; | ||
| 837 | strp += 2; /* skip \{ or \< */ | 847 | strp += 2; /* skip \{ or \< */ |
| 838 | start = strp; | 848 | start = strp; |
| 839 | start_idx = start - SDATA (string); | 849 | start_idx = start - SDATA (string); |
| @@ -903,6 +913,7 @@ Otherwise, return a new string. */) | |||
| 903 | length = SCHARS (tem); | 913 | length = SCHARS (tem); |
| 904 | length_byte = SBYTES (tem); | 914 | length_byte = SBYTES (tem); |
| 905 | subst: | 915 | subst: |
| 916 | changed = true; | ||
| 906 | { | 917 | { |
| 907 | ptrdiff_t offset = bufp - buf; | 918 | ptrdiff_t offset = bufp - buf; |
| 908 | if (STRING_BYTES_BOUND - length_byte < bsize) | 919 | if (STRING_BYTES_BOUND - length_byte < bsize) |
| @@ -916,6 +927,22 @@ Otherwise, return a new string. */) | |||
| 916 | strp = SDATA (string) + idx; | 927 | strp = SDATA (string) + idx; |
| 917 | } | 928 | } |
| 918 | } | 929 | } |
| 930 | else if (strp[0] == '`') | ||
| 931 | { | ||
| 932 | in_quote = true; | ||
| 933 | start = (unsigned char *) "\xE2\x80\x98"; /* ‘ */ | ||
| 934 | subst_quote: | ||
| 935 | length = 1; | ||
| 936 | length_byte = 3; | ||
| 937 | idx = strp - SDATA (string) + 1; | ||
| 938 | goto subst; | ||
| 939 | } | ||
| 940 | else if (strp[0] == '\'' && in_quote) | ||
| 941 | { | ||
| 942 | in_quote = false; | ||
| 943 | start = (unsigned char *) "\xE2\x80\x99"; /* ’ */ | ||
| 944 | goto subst_quote; | ||
| 945 | } | ||
| 919 | else if (! multibyte) /* just copy other chars */ | 946 | else if (! multibyte) /* just copy other chars */ |
| 920 | *bufp++ = *strp++, nchars++; | 947 | *bufp++ = *strp++, nchars++; |
| 921 | else | 948 | else |