aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2015-08-24 23:37:18 -0700
committerPaul Eggert2015-08-24 23:57:21 -0700
commit68280c5ee9b87d874ffa7c111b3cac7e634cee22 (patch)
tree955f3f692c7254074cac682c4e7e64b6f1361a35
parent0db4992d2778a2da4dee8ca07cde8c5e206f5250 (diff)
downloademacs-68280c5ee9b87d874ffa7c111b3cac7e634cee22.tar.gz
emacs-68280c5ee9b87d874ffa7c111b3cac7e634cee22.zip
Treat ' like ’ even when not matching `
This is simpler and easier to explain, and should encourage better typography. Do this in Electric Quote mode and when translating quotes in docstrings. Inspired by a suggestion by Dmitry Gutov in: https://lists.gnu.org/archive/html/emacs-devel/2015-08/msg00806.html * doc/emacs/text.texi (Quotation Marks): * doc/lispref/help.texi (Keys in Documentation): * etc/NEWS: Document this. * lisp/electric.el (electric-quote-post-self-insert-function): * src/doc.c (Fsubstitute_command_keys): Always treat ' like ’ even when not matched by an open quote.
-rw-r--r--doc/emacs/text.texi12
-rw-r--r--doc/lispref/help.texi20
-rw-r--r--etc/NEWS2
-rw-r--r--lisp/electric.el33
-rw-r--r--src/doc.c25
5 files changed, 32 insertions, 60 deletions
diff --git a/doc/emacs/text.texi b/doc/emacs/text.texi
index 5a13f208876..31760b70b4c 100644
--- a/doc/emacs/text.texi
+++ b/doc/emacs/text.texi
@@ -420,13 +420,11 @@ left and right single or double quotation marks @t{‘like this’} or
420@t{“like this”}. Typewriter quotes are simple and portable; curved 420@t{“like this”}. Typewriter quotes are simple and portable; curved
421quotes are less ambiguous and typically look nicer. 421quotes are less ambiguous and typically look nicer.
422 422
423 Electric Quote mode makes it easier to type curved quotes. It 423 Electric Quote mode makes it easier to type curved quotes. As you
424optionally converts a quotation's grave accent and apostrophe @t{`like 424type characters it optionally converts @t{`} to @t{‘}, @t{'} to @t{’},
425this'} to single quotation marks @t{‘like this’}. Similarly, it 425@t{``} to @t{“}, and @t{''} to @t{”}. These conversions are
426converts a quotation's double grave accent and double apostrophe 426suppressed in buffers whose coding systems cannot represent curved
427@t{``like this''} to double quotation marks @t{“like this”}. These 427quote characters.
428conversions are suppressed in buffers whose coding systems cannot
429represent curved quote characters.
430 428
431@vindex electric-quote-paragraph 429@vindex electric-quote-paragraph
432@vindex electric-quote-comment 430@vindex electric-quote-comment
diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi
index ab884f8dc80..44c09a2085a 100644
--- a/doc/lispref/help.texi
+++ b/doc/lispref/help.texi
@@ -318,25 +318,13 @@ stands for no text itself. It is used only for a side effect: it
318specifies @var{mapvar}'s value as the keymap for any following 318specifies @var{mapvar}'s value as the keymap for any following
319@samp{\[@var{command}]} sequences in this documentation string. 319@samp{\[@var{command}]} sequences in this documentation string.
320 320
321@item `
322(grave accent) stands for a left quote, and alters the interpretation
323of the next unmatched apostrophe.
324
325@item '
326(apostrophe) stands for a right quote if preceded by grave accent and
327there are no intervening apostrophes. Otherwise, apostrophe stands
328for itself.
329
330@item ‘ 321@item ‘
331(left single quotation mark) stands for a left quote. 322@itemx `
323(left single quotation mark and grave accent) both stand for a left quote.
332 324
333@item ’ 325@item ’
334(right single quotation mark) stands for a right quote. 326@itemx '
335 327(right single quotation mark and apostrophe) both stand for a right quote.
336@item '
337(apostrophe) stands for a right quote if
338preceded by grave accent and there are no intervening apostrophes.
339Otherwise, apostrophe stands for itself.
340 328
341@item \= 329@item \=
342quotes the following character and is discarded; thus, @samp{\=`} puts 330quotes the following character and is discarded; thus, @samp{\=`} puts
diff --git a/etc/NEWS b/etc/NEWS
index fd2ed4dd8af..89ab98d0692 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -923,7 +923,7 @@ Quotes in info files are not translated.
923That is, it converts documentation strings’ quoting style as per the 923That is, it converts documentation strings’ quoting style as per the
924value of ‘text-quoting-style’. Doc strings in source code can use 924value of ‘text-quoting-style’. Doc strings in source code can use
925either curved quotes or grave accent and apostrophe. As before, 925either curved quotes or grave accent and apostrophe. As before,
926isolated apostrophes and characters preceded by \= are output as-is. 926characters preceded by \= are output as-is.
927 927
928+++ 928+++
929** Message-issuing functions ‘error’, ‘message’, etc. now convert quotes. 929** Message-issuing functions ‘error’, ‘message’, etc. now convert quotes.
diff --git a/lisp/electric.el b/lisp/electric.el
index 8ca09316bcb..bef5bb9fec7 100644
--- a/lisp/electric.el
+++ b/lisp/electric.el
@@ -453,7 +453,7 @@ This requotes when a quoting key is typed."
453 (save-excursion 453 (save-excursion
454 (if (eq last-command-event ?\`) 454 (if (eq last-command-event ?\`)
455 (cond ((and (electric--insertable-p "“") 455 (cond ((and (electric--insertable-p "“")
456 (re-search-backward "[`]`" (- (point) 2) t)) 456 (search-backward "‘`" (- (point) 2) t))
457 (replace-match "“") 457 (replace-match "“")
458 (when (and electric-pair-mode 458 (when (and electric-pair-mode
459 (eq (cdr-safe 459 (eq (cdr-safe
@@ -465,19 +465,14 @@ This requotes when a quoting key is typed."
465 (search-backward "`" (1- (point)) t)) 465 (search-backward "`" (1- (point)) t))
466 (replace-match "‘") 466 (replace-match "‘")
467 (setq last-command-event ?‘))) 467 (setq last-command-event ?‘)))
468 (let ((pos (point))) 468 (cond ((and (electric--insertable-p "”")
469 (if (memq (char-before (1- (point))) '(?\' ?’)) 469 (search-backward "’'" (- (point) 2) t))
470 (when (and (search-backward "“" start t) 470 (replace-match "”")
471 (eq pos (re-search-forward 471 (setq last-command-event ?”))
472 "“\\(\\([^‘”]\\|‘[^‘’”]*’\\)*\\)['’]'" 472 ((and (electric--insertable-p "’")
473 pos t))) 473 (search-backward "'" (1- (point)) t))
474 (replace-match "“\\1”") 474 (replace-match "’")
475 (setq last-command-event ?”)) 475 (setq last-command-event ?’)))))))))
476 (when (and (search-backward "‘" start t)
477 (eq pos (re-search-forward
478 "‘\\([^’]*\\)'" pos t)))
479 (replace-match "‘\\1’")
480 (setq last-command-event ?’))))))))))
481 476
482(put 'electric-quote-post-self-insert-function 'priority 10) 477(put 'electric-quote-post-self-insert-function 'priority 10)
483 478
@@ -488,11 +483,11 @@ With a prefix argument ARG, enable Electric Quote mode if
488ARG is positive, and disable it otherwise. If called from Lisp, 483ARG is positive, and disable it otherwise. If called from Lisp,
489enable the mode if ARG is omitted or nil. 484enable the mode if ARG is omitted or nil.
490 485
491When enabled, this replaces \\=`foo bar' with \\=‘foo bar\\=’ and replaces 486When enabled, as you type this replaces \\=` with \\=‘, \\=' with \\=,
492\\=`\\=`foo bar'' with “foo bar” as you type. This occurs only in 487\\=`\\=` with “, and \\='\\=' with ”. This occurs only in comments, strings,
493comments, strings, and text paragraphs, and these are selectively 488and text paragraphs, and these are selectively controlled with
494controlled with ‘electric-quote-comment’, 489‘electric-quote-comment’, ‘electric-quote-string’, and
495‘electric-quote-string’, and ‘electric-quote-paragraph’. 490‘electric-quote-paragraph’.
496 491
497This is a global minor mode. To toggle the mode in a single buffer, 492This is a global minor mode. To toggle the mode in a single buffer,
498use ‘electric-quote-local-mode’." 493use ‘electric-quote-local-mode’."
diff --git a/src/doc.c b/src/doc.c
index 3c8b11d73f3..7a298e28631 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -731,10 +731,9 @@ summary).
731Each substring of the form \\=\\<MAPVAR> specifies the use of MAPVAR 731Each substring of the form \\=\\<MAPVAR> specifies the use of MAPVAR
732as the keymap for future \\=\\[COMMAND] substrings. 732as the keymap for future \\=\\[COMMAND] substrings.
733 733
734Each \\=‘ and \\=’ are replaced by left and right quote. Each \\=` is 734Each \\=‘ and \\=` is replaced by left quote, and each \\=’ and \\='
735replaced by left quote, and each ' preceded by \\=` and without 735is replaced by right quote. Left and right quote characters are
736intervening ' is replaced by right quote. Left and right quote 736specified by ‘text-quoting-style’.
737characters are specified by ‘text-quoting-style’.
738 737
739\\=\\= quotes the following character and is discarded; thus, 738\\=\\= quotes the following character and is discarded; thus,
740\\=\\=\\=\\= puts \\=\\= into the output, \\=\\=\\=\\[ puts \\=\\[ into the output, and 739\\=\\=\\=\\= puts \\=\\= into the output, \\=\\=\\=\\[ puts \\=\\[ into the output, and
@@ -746,7 +745,6 @@ Otherwise, return a new string. */)
746{ 745{
747 char *buf; 746 char *buf;
748 bool changed = false; 747 bool changed = false;
749 bool in_quote = false;
750 unsigned char *strp; 748 unsigned char *strp;
751 char *bufp; 749 char *bufp;
752 ptrdiff_t idx; 750 ptrdiff_t idx;
@@ -971,11 +969,10 @@ Otherwise, return a new string. */)
971 strp = SDATA (string) + idx; 969 strp = SDATA (string) + idx;
972 } 970 }
973 } 971 }
974 else if (strp[0] == '`' && quoting_style == CURVE_QUOTING_STYLE) 972 else if ((strp[0] == '`' || strp[0] == '\'')
973 && quoting_style == CURVE_QUOTING_STYLE)
975 { 974 {
976 in_quote = true; 975 start = strp[0] == '`' ? LSQM : RSQM;
977 start = LSQM;
978 subst_quote:
979 length = 1; 976 length = 1;
980 length_byte = 3; 977 length_byte = 3;
981 idx = strp - SDATA (string) + 1; 978 idx = strp - SDATA (string) + 1;
@@ -988,12 +985,6 @@ Otherwise, return a new string. */)
988 nchars++; 985 nchars++;
989 changed = true; 986 changed = true;
990 } 987 }
991 else if (strp[0] == '\'' && in_quote)
992 {
993 in_quote = false;
994 start = RSQM;
995 goto subst_quote;
996 }
997 else if (strp[0] == uLSQM0 && strp[1] == uLSQM1 988 else if (strp[0] == uLSQM0 && strp[1] == uLSQM1
998 && (strp[2] == uLSQM2 || strp[2] == uRSQM2) 989 && (strp[2] == uLSQM2 || strp[2] == uRSQM2)
999 && quoting_style != CURVE_QUOTING_STYLE) 990 && quoting_style != CURVE_QUOTING_STYLE)
@@ -1108,8 +1099,8 @@ syms_of_doc (void)
1108 DEFVAR_LISP ("text-quoting-style", Vtext_quoting_style, 1099 DEFVAR_LISP ("text-quoting-style", Vtext_quoting_style,
1109 doc: /* Style to use for single quotes when generating text. 1100 doc: /* Style to use for single quotes when generating text.
1110‘curve’ means quote with curved single quotes \\=‘like this\\=’. 1101‘curve’ means quote with curved single quotes \\=‘like this\\=’.
1111‘straight’ means quote with straight apostrophes 'like this'. 1102‘straight’ means quote with straight apostrophes \\='like this\\='.
1112‘grave’ means quote with grave accent and apostrophe \\=`like this'. 1103‘grave’ means quote with grave accent and apostrophe \\=`like this\\='.
1113The default value nil acts like ‘curve’ if curved single quotes are 1104The default value nil acts like ‘curve’ if curved single quotes are
1114displayable, and like ‘grave’ otherwise. */); 1105displayable, and like ‘grave’ otherwise. */);
1115 Vtext_quoting_style = Qnil; 1106 Vtext_quoting_style = Qnil;