* bug#20545: New minor mode Electric Punct @ 2015-05-10 23:55 Paul Eggert 2015-05-11 15:00 ` Eli Zaretskii ` (3 more replies) 0 siblings, 4 replies; 26+ messages in thread From: Paul Eggert @ 2015-05-10 23:55 UTC (permalink / raw) To: 20545 [-- Attachment #1: Type: text/plain, Size: 1118 bytes --] Attached are two proposed patches. The first creates a new minor mode Electric Punct that does a variant of "smart quoting" designed for the Emacs tradition of using ` and ' as aliases for left and right single quotation marks. This new minor mode is inactive by default, but the user can enable it in certain contexts. The second patch modifies .dir-locals.el to enable the minor mode in contexts where it should be useful when editing Emacs itself. These patches are related to Bug#20385 in that they make it much easier to edit doc strings formatted ‘like this’, which is the point of Bug#20385. (All that one needs to do is to type the string "`like this'".) However, the main idea of this patch is independent of the Emacs doc string issue, as Emacs should make it easy to quote ‘like this’ when the user prefers this form. I named this mode "Electric Punct" because I anticipate that there may be a similar need to enter em and en dashes, and a few other non-ASCII punctuation marks commonly used in text. Quotes are a good place to start, so that's where I started. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-New-minor-mode-Electric-Punct.patch --] [-- Type: text/x-patch; name="0001-New-minor-mode-Electric-Punct.patch", Size: 10515 bytes --] From 106bdf81a5d27e6b055da002f8f000614268a8a1 Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert@cs.ucla.edu> Date: Sun, 10 May 2015 16:06:05 -0700 Subject: [PROPOSED PATCH 1/2] New minor mode Electric Punct * doc/emacs/basic.texi (Inserting Text): Briefly mention how to insert curved quotation marks. * doc/emacs/modes.texi (Minor Modes): Mention Electric Punct mode. * doc/emacs/text.texi (Punctuation): New section. * etc/NEWS: Mention this. * lisp/electric.el (electric-punct-comment) (electric-punct-string, electric-punct-paragraph): New custom vars. (electric-punct-post-self-insert-function): New function. (electric-punct-mode, electric-punct-local-mode): New minor modes. --- doc/emacs/basic.texi | 7 ++++ doc/emacs/modes.texi | 9 +++++ doc/emacs/text.texi | 38 ++++++++++++++++++++++ etc/NEWS | 3 +- lisp/electric.el | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 148 insertions(+), 1 deletion(-) diff --git a/doc/emacs/basic.texi b/doc/emacs/basic.texi index be45856..2ade172 100644 --- a/doc/emacs/basic.texi +++ b/doc/emacs/basic.texi @@ -127,6 +127,13 @@ sign (Unicode code-point @code{U+221E}): A numeric argument to @kbd{C-q} or @kbd{C-x 8 @key{RET}} specifies how many copies of the character to insert (@pxref{Arguments}). + In some contexts, if you type a quotation using grave accent and +apostrophe @samp{`like this'}, it is converted to a form @samp{‘like +this’} using single quotation marks. Similarly, typing a quotation +@samp{``like this''} using double grave accent and apostrophe converts +it to a form @samp{“like this”} using double quotation marks. +@xref{Punctuation}. + @node Moving Point @section Changing the Location of Point diff --git a/doc/emacs/modes.texi b/doc/emacs/modes.texi index 0e8f46a..98a8858 100644 --- a/doc/emacs/modes.texi +++ b/doc/emacs/modes.texi @@ -200,6 +200,15 @@ Auto Save mode saves the buffer contents periodically to reduce the amount of work you can lose in case of a crash. @xref{Auto Save}. @item +@cindex Electric Punct mode +@cindex mode, Electric Punct +@findex electric-punct-mode +Electric Punct mode automatically converts some punctation marks. For +example, it requotes text typed @samp{`like this'} to text @samp{‘like +this’}. You can control what kind of text it operates in, and you can +disable it entirely in individual buffers. @xref{Punctuation}. + +@item Enriched mode enables editing and saving of formatted text. @xref{Enriched Text}. diff --git a/doc/emacs/text.texi b/doc/emacs/text.texi index 9bc5ade..06eb4fd 100644 --- a/doc/emacs/text.texi +++ b/doc/emacs/text.texi @@ -69,6 +69,7 @@ for editing such pictures. * Sentences:: Moving over and killing sentences. * Paragraphs:: Moving over paragraphs. * Pages:: Moving over pages. +* Punctuation:: Inserting punctuation. * Filling:: Filling or justifying text. * Case:: Changing the case of text. * Text Mode:: The major modes for editing text files. @@ -404,6 +405,43 @@ that separates pages (@pxref{Regexps}). The normal value of this variable is @code{"^\f"}, which matches a formfeed character at the beginning of a line. +@node Punctuation +@section Punctuation +@cindex Punctuation +@cindex Quotation marks +@cindex Electric Punct mode +@cindex mode, Electric Punct + One common way to quote is the typewriter convention, which quotes +uses apostrophes @samp{'like this'} or double-quotes @samp{"like +this"}. Another common way is the curved quote convention, which uses +left and right single and double quotation marks @samp{‘like this’} or +@samp{“like this”}. Typewriter quotes are simple and portable; curved +quotes are unambiguous and look nicer. + + Electric Punct mode makes it easier to type curved quotes. It +optionally converts a quotation using grave accent and apostrophe +@samp{`like this'}, to a form using single quotation marks @samp{‘like +this’}. Similarly, it converts a quotation using double grave accent +and double apostrophe @samp{``like this''} to a form using double +quotation marks @samp{“like this”}. + + You can customize the behavior of Electric Punct mode by setting +variables that control where it is active. If +@code{electric-punct-comment} is non-nil, it is active within +programming-language comments; if @code{electric-punct-string} is +non-nil, it is active within programming-language strings; and if +@code{electric-punct-paragraph} is non-nil, it is active within text +paragraphs. These variables default to nil, which causes Electric +Punct mode to be inactive everywhere. + + Electric Punct mode is enabled by default. To suppress it for a +single use, type @kbd{C-q `} or @kbd{C-q '} instead of @kbd{`} or +@kbd{'}. To toggle it, type @kbd{M-x electric-punct-mode}. To toggle +it in a single buffer, use @kbd{M-x electric-punct-local-mode}. To +insert a curved quote even when Electric Punct is disabled or +inactive, use @kbd{C-x 8 @key{RET}} (@code{insert-char}). +@xref{Inserting Text}. + @node Filling @section Filling Text @cindex filling text diff --git a/etc/NEWS b/etc/NEWS index 844181c..61a2c35 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -213,7 +213,8 @@ successive char insertions. ** Unicode names entered via C-x 8 RET now use substring completion by default. -** New minor mode global-eldoc-mode is enabled by default. +** New minor modes electric-punct-mode and global-eldoc-mode +are enabled by default. ** Emacs now supports "bracketed paste mode" when running on a terminal that supports it. This facility allows Emacs to understand pasted diff --git a/lisp/electric.el b/lisp/electric.el index dd7767f..bac1918 100644 --- a/lisp/electric.el +++ b/lisp/electric.el @@ -413,6 +413,98 @@ The variable `electric-layout-rules' says when and how to insert newlines." (remove-hook 'post-self-insert-hook #'electric-layout-post-self-insert-function)))) +;;; Electric punctuation. + +(defcustom electric-punct-comment nil + "Non-nil means to use electric punctuation in program comments." + :type 'boolean :safe 'booleanp :group 'electricity) + +(defcustom electric-punct-string nil + "Non-nil means to use electric punctuation in program strings." + :type 'boolean :safe 'booleanp :group 'electricity) + +(defcustom electric-punct-paragraph nil + "Non-nil means to use electric punctuation in text paragraphs." + :type 'boolean :safe 'booleanp :group 'electricity) + +(defun electric-punct-post-self-insert-function () + "Function that ‘electric-punct-mode’ adds to ‘post-self-insert-hook’. +This repunctuates when a punctuation key is typed." + (when (and electric-punct-mode enable-multibyte-characters + (memq last-command-event '(?' ?`))) + (let ((start + (if comment-start + (when (or electric-punct-comment electric-punct-string) + (let ((syntax (syntax-ppss))) + (and (or (and electric-punct-comment (nth 4 syntax)) + (and electric-punct-string (nth 3 syntax))) + (nth 8 syntax)))) + (and electric-punct-paragraph + (derived-mode-p 'text-mode) + (or (eq last-command-event ?`) + (save-excursion (backward-paragraph) (point))))))) + (when start + (save-excursion + (if (eq last-command-event ?`) + (cond ((re-search-backward "[`‘]`" (- (point) 2) t) + (replace-match "“")) + ((search-backward "`" (1- (point)) t) + (replace-match "‘"))) + (let ((pos (point))) + (if (memq (char-before (1- (point))) '(?' ?’)) + (when (and (search-backward "“" start t) + (eq pos (re-search-forward + "“\\([^”]*\\)['’]'" pos t))) + (replace-match "“\\1”")) + (when (and (search-backward "‘" start t) + (eq pos (re-search-forward + "‘\\([^’]*\\)'" pos t))) + (replace-match "‘\\1’")))))))))) + +(put 'electric-punct-post-self-insert-function 'priority 60) + +;;;###autoload +(define-minor-mode electric-punct-mode + "Toggle on-the-fly repunctuation (Electric Punctuation mode). +With a prefix argument ARG, enable Electric Punctuation mode if +ARG is positive, and disable it otherwise. If called from Lisp, +enable the mode if ARG is omitted or nil. + +When enabled, this replaces `foo bar' with ‘foo bar’ and replaces +``foo bar'' with “foo bar” as you type. This occurs only in +comments, strings, and text paragraphs, and these are selectively +controlled with ‘electric-punct-comment’, +‘electric-punct-string’, and ‘electric-punct-paragraph’. + +This is a global minor mode. To toggle the mode in a single buffer, +use ‘electric-punct-local-mode’." + :global t :group 'electricity + :initialize 'custom-initialize-delay + :init-value t + (if (not electric-punct-mode) + (unless (catch 'found + (dolist (buf (buffer-list)) + (with-current-buffer buf + (if electric-punct-mode (throw 'found t))))) + (remove-hook 'post-self-insert-hook + #'electric-punct-post-self-insert-function)) + (add-hook 'post-self-insert-hook + #'electric-punct-post-self-insert-function) + (electric--sort-post-self-insertion-hook))) + +;;;###autoload +(define-minor-mode electric-punct-local-mode + "Toggle ‘electric-punct-mode’ only in this buffer." + :variable (buffer-local-value 'electric-punct-mode (current-buffer)) + (cond + ((eq electric-punct-mode (default-value 'electric-punct-mode)) + (kill-local-variable 'electric-punct-mode)) + ((not (default-value 'electric-punct-mode)) + ;; Locally enabled, but globally disabled. + (electric-punct-mode 1) ; Setup the hooks. + (setq-default electric-punct-mode nil) ; But keep it globally disabled. + ))) + (provide 'electric) ;;; electric.el ends here -- 2.1.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #3: 0002-Use-Electric-Punct-when-editing-Emacs-source.patch --] [-- Type: text/x-patch; name="0002-Use-Electric-Punct-when-editing-Emacs-source.patch", Size: 1437 bytes --] From 401bf3e899ac84d062c86da469c33c662f969ef8 Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert@cs.ucla.edu> Date: Sun, 10 May 2015 16:07:13 -0700 Subject: [PROPOSED PATCH 2/2] Use Electric Punct when editing Emacs source MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a companion to the patch proposed in Bug#20385. The idea is to let maintainers quote ‘like this’ in doc strings just as easily as they traditionally quote `like this'. * .dir-locals.el: Add electric-punct-comment, electric-punct-paragraph. (emacs-lisp-mode): Add electric-punct-string. --- .dir-locals.el | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.dir-locals.el b/.dir-locals.el index 9853d7b..9c73abe 100644 --- a/.dir-locals.el +++ b/.dir-locals.el @@ -1,5 +1,7 @@ ((nil . ((tab-width . 8) (sentence-end-double-space . t) + (electric-punct-comment . t) + (electric-punct-paragraph . t) (fill-column . 70))) (c-mode . ((c-file-style . "GNU"))) (objc-mode . ((c-file-style . "GNU"))) @@ -10,4 +12,5 @@ (bug-reference-url-format . "http://debbugs.gnu.org/%s") (mode . bug-reference))) (diff-mode . ((mode . whitespace))) - (emacs-lisp-mode . ((indent-tabs-mode . nil)))) + (emacs-lisp-mode . ((electric-punct-string . t) + (indent-tabs-mode . nil)))) -- 2.1.0 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Punct 2015-05-10 23:55 bug#20545: New minor mode Electric Punct Paul Eggert @ 2015-05-11 15:00 ` Eli Zaretskii 2015-05-13 7:48 ` Paul Eggert 2015-05-11 15:57 ` bug#20545: New minor mode Electric Punct Stefan Monnier ` (2 subsequent siblings) 3 siblings, 1 reply; 26+ messages in thread From: Eli Zaretskii @ 2015-05-11 15:00 UTC (permalink / raw) To: Paul Eggert; +Cc: 20545 > Date: Sun, 10 May 2015 16:55:42 -0700 > From: Paul Eggert <eggert@cs.ucla.edu> > > Attached are two proposed patches. The first creates a new minor mode Electric Punct that does a variant of "smart quoting" designed for the Emacs tradition of using ` and ' as aliases for left and right single quotation marks. This new minor mode is inactive by default The documentation patch says it's enabled by default. > but the user can enable it in certain contexts. The second patch modifies .dir-locals.el to enable the minor mode in contexts where it should be useful when editing Emacs itself. I don't think we should enable this by default, not even in .dir-locals.el. Let users decide whether they want this; as for Emacs, we didn't yet decide this style to be mandatory, so it's too early to force it. > These patches are related to Bug#20385 in that they make it much easier to edit doc strings formatted ‘like this’, which is the point of Bug#20385. Do we already have a way of displaying ‘..’ on terminals that cannot display them (notably, some TTYs)? If not, we should add that before we install these changes, and those in bug #20385. I don't think we can let doc strings have glyphless characters. ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Punct 2015-05-11 15:00 ` Eli Zaretskii @ 2015-05-13 7:48 ` Paul Eggert 2015-05-13 13:10 ` Stefan Monnier 2015-05-13 16:38 ` Eli Zaretskii 0 siblings, 2 replies; 26+ messages in thread From: Paul Eggert @ 2015-05-13 7:48 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 20545 Eli Zaretskii wrote: > The documentation patch says it's enabled by default. It's enabled, but the variables that configure it make it inactive by default. I'll try to make this clearer in the documentation. > I don't think we should enable this by default, not even in > .dir-locals.el. We can certainly hold off on the .dir-locals.el part for a bit, to see how it works for developers who want to try it. > Do we already have a way of displaying ‘..’ on terminals that cannot > display them (notably, some TTYs)? If not, we should add that before > we install these changes, and those in bug #20385. I don't think we > can let doc strings have glyphless characters. I just now configured a terminal to refuse to display curved quotes, and when I used it Emacs displayed "‘like this’" as "\u2018like this\u2019" with underscores below the "\u2018" and the "\u2019". I could easily change it to display it as "`like this'" with underscores under the "`" and the "'", if you think that'd be a win. ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Punct 2015-05-13 7:48 ` Paul Eggert @ 2015-05-13 13:10 ` Stefan Monnier 2015-05-13 14:49 ` Paul Eggert 2015-05-13 16:54 ` Eli Zaretskii 2015-05-13 16:38 ` Eli Zaretskii 1 sibling, 2 replies; 26+ messages in thread From: Stefan Monnier @ 2015-05-13 13:10 UTC (permalink / raw) To: Paul Eggert; +Cc: 20545 > I just now configured a terminal to refuse to display curved quotes, and > when I used it Emacs displayed "‘like this’" as "\u2018like this\u2019" with > underscores below the "\u2018" and the "\u2019". Hmm... is it really Emacs that displayed it like this? Or is it the terminal which did it? If it's Emacs, then I wonder how it figured it needed to do that, and if it's the terminal, then I wonder how Emacs could tell the terminal to... > ... display it as "`like this'" with underscores under the "`" and the "'", > if you think that'd be a win. Stefan ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Punct 2015-05-13 13:10 ` Stefan Monnier @ 2015-05-13 14:49 ` Paul Eggert 2015-05-13 17:05 ` Eli Zaretskii 2015-05-14 3:52 ` Stefan Monnier 2015-05-13 16:54 ` Eli Zaretskii 1 sibling, 2 replies; 26+ messages in thread From: Paul Eggert @ 2015-05-13 14:49 UTC (permalink / raw) To: Stefan Monnier; +Cc: 20545 [-- Attachment #1: Type: text/plain, Size: 627 bytes --] Stefan Monnier wrote: > Hmm... is it really Emacs that displayed it like this? Or is it the > terminal which did it? If it's Emacs, then I wonder how it figured it > needed to do that I haven't looked at the details, but I expect Emacs looks at the locale and discovers that it's unibyte. At least, that's how I did it: by starting xterm in an Ubuntu 15.04 environment where LC_ALL=en_US.iso885915, and then running emacs -nw under xterm. In this situation, the attached patch to Emacs (which would have to be improved before installing) has the behavior of using underlined ` and ' to render curved single quotes. [-- Attachment #2: patch.diff --] [-- Type: text/x-patch, Size: 412 bytes --] diff --git a/src/term.c b/src/term.c index d2a9c3d..86ca4d8 100644 --- a/src/term.c +++ b/src/term.c @@ -1867,6 +1867,10 @@ produce_glyphless_glyph (struct it *it, Lisp_Object acronym) : it->c <= MAX_UNICODE_CHAR ? "\\U%06X" : "\\x%06X"), it->c + 0u); + if (it->c == 0x2018) + buf[0] = '`', len = 1; + else if (it->c == 0x2019) + buf[0] = '\'', len = 1; } str = buf; } ^ permalink raw reply related [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Punct 2015-05-13 14:49 ` Paul Eggert @ 2015-05-13 17:05 ` Eli Zaretskii 2015-05-14 3:52 ` Stefan Monnier 1 sibling, 0 replies; 26+ messages in thread From: Eli Zaretskii @ 2015-05-13 17:05 UTC (permalink / raw) To: Paul Eggert; +Cc: 20545 > Date: Wed, 13 May 2015 07:49:47 -0700 > From: Paul Eggert <eggert@cs.ucla.edu> > CC: Eli Zaretskii <eliz@gnu.org>, 20545@debbugs.gnu.org > > In this situation, the attached patch to Emacs (which would have to > be improved before installing) has the behavior of using underlined > ` and ' to render curved single quotes. > > diff --git a/src/term.c b/src/term.c > index d2a9c3d..86ca4d8 100644 > --- a/src/term.c > +++ b/src/term.c > @@ -1867,6 +1867,10 @@ produce_glyphless_glyph (struct it *it, Lisp_Object acronym) > : it->c <= MAX_UNICODE_CHAR ? "\\U%06X" > : "\\x%06X"), > it->c + 0u); > + if (it->c == 0x2018) > + buf[0] = '`', len = 1; > + else if (it->c == 0x2019) > + buf[0] = '\'', len = 1; I think we should use a display table here, like we do with other special characters. Hard-coding the replacements sounds un-Emacsy. Thanks. ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Punct 2015-05-13 14:49 ` Paul Eggert 2015-05-13 17:05 ` Eli Zaretskii @ 2015-05-14 3:52 ` Stefan Monnier 2015-05-14 14:54 ` Eli Zaretskii 1 sibling, 1 reply; 26+ messages in thread From: Stefan Monnier @ 2015-05-14 3:52 UTC (permalink / raw) To: Paul Eggert; +Cc: 20545 > discovers that it's unibyte. At least, that's how I did it: by starting > xterm in an Ubuntu 15.04 environment where LC_ALL=en_US.iso885915, and then Oh, but that's the easy case. The real test is when the environment uses utf-8 but the terminal's font fails to include the glyphs. Stefan ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Punct 2015-05-14 3:52 ` Stefan Monnier @ 2015-05-14 14:54 ` Eli Zaretskii 0 siblings, 0 replies; 26+ messages in thread From: Eli Zaretskii @ 2015-05-14 14:54 UTC (permalink / raw) To: Stefan Monnier; +Cc: 20545, eggert > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: Eli Zaretskii <eliz@gnu.org>, 20545@debbugs.gnu.org > Date: Wed, 13 May 2015 23:52:35 -0400 > > > discovers that it's unibyte. At least, that's how I did it: by starting > > xterm in an Ubuntu 15.04 environment where LC_ALL=en_US.iso885915, and then > > Oh, but that's the easy case. The real test is when the environment > uses utf-8 but the terminal's font fails to include the glyphs. IOW, the terminal supports UTF-8, but the font it uses doesn't have these characters covered? Is that something that is likely to happen in real life? I was under the impression that the General Punctuation block was well covered in UTF-8 locales in general, and in fonts used for the default text when UTF-8 encoding is supported, in particular. But if that's not the case, we could provide a user option to forcibly use the display table with ASCII glyphs for these characters, even if char-displayable-p says they can be displayed. ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Punct 2015-05-13 13:10 ` Stefan Monnier 2015-05-13 14:49 ` Paul Eggert @ 2015-05-13 16:54 ` Eli Zaretskii 1 sibling, 0 replies; 26+ messages in thread From: Eli Zaretskii @ 2015-05-13 16:54 UTC (permalink / raw) To: Stefan Monnier; +Cc: 20545, eggert > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: Eli Zaretskii <eliz@gnu.org>, 20545@debbugs.gnu.org > Date: Wed, 13 May 2015 09:10:07 -0400 > > > I just now configured a terminal to refuse to display curved quotes, and > > when I used it Emacs displayed "‘like this’" as "\u2018like this\u2019" with > > underscores below the "\u2018" and the "\u2019". > > Hmm... is it really Emacs that displayed it like this? Or is it the > terminal which did it? Emacs. That's how we display "glyphless" characters on a TTY. > If it's Emacs, then I wonder how it figured it needed to do that, By checking whether the character belongs to one of the charsets supported by the terminal. We call char_charset with the list of charsets supported by the terminal frame; that charset list is set by set-terminal-coding-system-internal. See the end of term.c:produce_glyphs. > and if it's the terminal, then I wonder how Emacs could tell the > terminal to... > > > ... display it as "`like this'" with underscores under the "`" and the "'", > > if you think that'd be a win. We could discover this in advance (e.g., using char-displayable-p) and use a display table, for example. ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Punct 2015-05-13 7:48 ` Paul Eggert 2015-05-13 13:10 ` Stefan Monnier @ 2015-05-13 16:38 ` Eli Zaretskii 2015-05-13 16:56 ` Paul Eggert 1 sibling, 1 reply; 26+ messages in thread From: Eli Zaretskii @ 2015-05-13 16:38 UTC (permalink / raw) To: Paul Eggert; +Cc: 20545 > Date: Wed, 13 May 2015 00:48:13 -0700 > From: Paul Eggert <eggert@cs.ucla.edu> > CC: 20545@debbugs.gnu.org > > Do we already have a way of displaying ‘..’ on terminals that cannot > display them (notably, some TTYs)? If not, we should add that before > we install these changes, and those in bug #20385. I don't think we > can let doc strings have glyphless characters. > > I just now configured a terminal to refuse to display curved quotes, and when I used it Emacs displayed "‘like this’" as "\u2018like this\u2019" with underscores below the "\u2018" and the "\u2019". Yes, that's what I see, too. > I could easily change it to display it as "`like this'" with underscores under the "`" and the "'", if you think that'd be a win. I think we should indeed display that `like this' (when the curved quotes cannot be displayed), but do we really need the underscores? What would be their purpose? Thanks. ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Punct 2015-05-13 16:38 ` Eli Zaretskii @ 2015-05-13 16:56 ` Paul Eggert 2015-05-13 17:16 ` Eli Zaretskii 0 siblings, 1 reply; 26+ messages in thread From: Paul Eggert @ 2015-05-13 16:56 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 20545 Eli Zaretskii wrote: > do we really need the underscores? > What would be their purpose? To tell the user that the characters are not really "`" and "'", but are something else. It's the same reason we underline the "\u2018" and the "\u2019". ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Punct 2015-05-13 16:56 ` Paul Eggert @ 2015-05-13 17:16 ` Eli Zaretskii 2015-05-13 18:10 ` Eli Zaretskii 2015-05-14 6:32 ` Paul Eggert 0 siblings, 2 replies; 26+ messages in thread From: Eli Zaretskii @ 2015-05-13 17:16 UTC (permalink / raw) To: Paul Eggert; +Cc: 20545 > Date: Wed, 13 May 2015 09:56:12 -0700 > From: Paul Eggert <eggert@cs.ucla.edu> > CC: 20545@debbugs.gnu.org > > Eli Zaretskii wrote: > > do we really need the underscores? > > What would be their purpose? > > To tell the user that the characters are not really "`" and "'", but are > something else. I fear it will just be a source of confusion. FWIW, when Texinfo's Info reader makes similar replacements, it doesn't mark them in any way, so the user really doesn't know the characters were replaced. ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Punct 2015-05-13 17:16 ` Eli Zaretskii @ 2015-05-13 18:10 ` Eli Zaretskii 2015-05-14 6:32 ` Paul Eggert 1 sibling, 0 replies; 26+ messages in thread From: Eli Zaretskii @ 2015-05-13 18:10 UTC (permalink / raw) To: eggert; +Cc: 20545 > Date: Wed, 13 May 2015 20:16:23 +0300 > From: Eli Zaretskii <eliz@gnu.org> > Cc: 20545@debbugs.gnu.org > > > Date: Wed, 13 May 2015 09:56:12 -0700 > > From: Paul Eggert <eggert@cs.ucla.edu> > > CC: 20545@debbugs.gnu.org > > > > Eli Zaretskii wrote: > > > do we really need the underscores? > > > What would be their purpose? > > > > To tell the user that the characters are not really "`" and "'", but are > > something else. > > I fear it will just be a source of confusion. FWIW, when Texinfo's > Info reader makes similar replacements, it doesn't mark them in any > way, so the user really doesn't know the characters were replaced. If you still think we should highlight these characters, then let's at least do that in the same manner as we do with non-ASCII hyphen, conditioned on nobreak-char-display (see xdisp.c around line 6900 for the details). ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Punct 2015-05-13 17:16 ` Eli Zaretskii 2015-05-13 18:10 ` Eli Zaretskii @ 2015-05-14 6:32 ` Paul Eggert 2015-05-16 21:20 ` Paul Eggert 1 sibling, 1 reply; 26+ messages in thread From: Paul Eggert @ 2015-05-14 6:32 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 20545 [-- Attachment #1: Type: text/plain, Size: 830 bytes --] Eli Zaretskii wrote: > I fear it will just be a source of confusion. Well, 8-bit terminals are no longer that common (at least when developing Emacs) so it's no big deal either way, and as it's easier to do it without highlighting let's try it that way. A proposed patch is attached; it worked for me. Stefan Monnier wrote: > The real test is when the environment > uses utf-8 but the terminal's font fails to include the glyphs. That can easily happen with other characters, but in practice nowadays I think everybody has glyphs for curved quotes. This is in part due to Microsoft Windows putting curved quotes in their most-popular 8-bit character set starting with MS-Windows 1.0 in 1985. This put a lot of pressure on everybody else to support these glyphs one way or another, and it has been thirty years now.... [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Work-better-on-terminals-sans-curved-single-quotes.patch --] [-- Type: text/x-patch; name="0001-Work-better-on-terminals-sans-curved-single-quotes.patch", Size: 1302 bytes --] From dd42a7ba816df0d209c0f1e965ee036c62c0337a Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert@cs.ucla.edu> Date: Wed, 13 May 2015 23:15:23 -0700 Subject: [PATCH] Work better on terminals sans curved single quotes * lisp/international/mule-cmds.el (set-locale-environment): If single quotation marks are not displayable, show ASCII approximations instead. --- lisp/international/mule-cmds.el | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el index fd892aa..2805671 100644 --- a/lisp/international/mule-cmds.el +++ b/lisp/international/mule-cmds.el @@ -2708,6 +2708,13 @@ See also `locale-charset-language-names', `locale-language-names', (set-terminal-coding-system 'utf-8) (set-keyboard-coding-system 'utf-8))) + ;; If single quotation marks don't work, display ASCII approximations. + (dolist (char-repl '((?‘ . [?\`]) (?’ . [?\']))) + (when (not (char-displayable-p (car char-repl))) + (or standard-display-table + (setq standard-display-table (make-display-table))) + (aset standard-display-table (car char-repl) (cdr char-repl)))) + ;; Default to A4 paper if we're not in a C, POSIX or US locale. ;; (See comments in Flocale_info.) (unless frame -- 2.1.0 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Punct 2015-05-14 6:32 ` Paul Eggert @ 2015-05-16 21:20 ` Paul Eggert 2015-05-17 14:33 ` Eli Zaretskii 0 siblings, 1 reply; 26+ messages in thread From: Paul Eggert @ 2015-05-16 21:20 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 20545 [-- Attachment #1: Type: text/plain, Size: 534 bytes --] Paul Eggert wrote: > A proposed patch is attached; it worked for me. On further thought, the code affects global settings so it should be done only if FRAME is nil. Also, it should treat double-quotes like single-quotes, and the ASCII approximations should use straight quotes. This code is separable from Bug#20545, and is also separable from the issue of how to quote in doc strings, as the code is useful whenever text with English quotes appears on an obsolescent display lacking them. So I installed the attached patch. [-- Attachment #2: 0001-ASCIIfy-curved-quotes-on-displays-lacking-them.txt --] [-- Type: text/plain, Size: 1357 bytes --] From a92e964a9809ada92b29b23ab6191fc7f3faad4d Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert@cs.ucla.edu> Date: Sat, 16 May 2015 13:47:36 -0700 Subject: [PATCH] ASCIIfy curved quotes on displays lacking them * lisp/international/mule-cmds.el (set-locale-environment): If curved quotes don't work, display straight ASCII approximations (Bug#20545). --- lisp/international/mule-cmds.el | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el index fd892aa..4b63cb8 100644 --- a/lisp/international/mule-cmds.el +++ b/lisp/international/mule-cmds.el @@ -2708,6 +2708,14 @@ See also `locale-charset-language-names', `locale-language-names', (set-terminal-coding-system 'utf-8) (set-keyboard-coding-system 'utf-8))) + ;; If curved quotes don't work, display straight ASCII approximations. + (unless frame + (dolist (char-repl '((?‘ . [?\']) (?’ . [?\']) (?“ . [?\"]) (?” . [?\"]))) + (when (not (char-displayable-p (car char-repl))) + (or standard-display-table + (setq standard-display-table (make-display-table))) + (aset standard-display-table (car char-repl) (cdr char-repl))))) + ;; Default to A4 paper if we're not in a C, POSIX or US locale. ;; (See comments in Flocale_info.) (unless frame -- 2.1.0 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Punct 2015-05-16 21:20 ` Paul Eggert @ 2015-05-17 14:33 ` Eli Zaretskii 2015-05-17 16:58 ` Paul Eggert 0 siblings, 1 reply; 26+ messages in thread From: Eli Zaretskii @ 2015-05-17 14:33 UTC (permalink / raw) To: Paul Eggert; +Cc: 20545 > Date: Sat, 16 May 2015 14:20:39 -0700 > From: Paul Eggert <eggert@cs.ucla.edu> > CC: 20545@debbugs.gnu.org > > On further thought, the code affects global settings so it should be done only if FRAME is nil. Also, it should treat double-quotes like single-quotes, and the ASCII approximations should use straight quotes. This code is separable from Bug#20545, and is also separable from the issue of how to quote in doc strings, as the code is useful whenever text with English quotes appears on an obsolescent display lacking them. So I installed the attached patch. Yes, this global effect is not a Good Thing. It means that a buffer with these characters that is displayed on a TTY frame and on a GUI frame will use the substitutes on both. Btw, is set-locale-environment called when a new frame is created? If not, then this is not a proper place to install the display table, as it won't DTRT when a new TTY frame is created in a running Emacs session, and that frame displays on a terminal that doesn't support these characters. I think it would be better to install this as a window-specific display table, using set-window-display-table, as part of setting up the window showing the *Help* buffer. WDYT? ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Punct 2015-05-17 14:33 ` Eli Zaretskii @ 2015-05-17 16:58 ` Paul Eggert 2015-05-17 19:04 ` Eli Zaretskii 0 siblings, 1 reply; 26+ messages in thread From: Paul Eggert @ 2015-05-17 16:58 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 20545 Eli Zaretskii wrote: > is set-locale-environment called when a new frame is created? Yes, but in that case FRAME is non-nil, so this new code isn't executed. It's executed only during startup. > I think it would be better to install this as a window-specific > display table, using set-window-display-table, as part of setting up > the window showing the*Help* buffer. WDYT? Having it be window-specific, or better yet frame-specific, would be an improvement, but it shouldn't be limited to *Help* buffers, as other kinds of buffers can have curved quotes. I'm not sure I'd worry about it. First, the kind of user likely to be running multidisplay is not the kind of user likely to be starting up in an obsolescent 8-bit locale. Second, if someone really does both things, they'll probably run into other problems anyway. Third, this particular problem, for the rare user who runs into it, will be just a minor glitch. ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Punct 2015-05-17 16:58 ` Paul Eggert @ 2015-05-17 19:04 ` Eli Zaretskii 2015-06-01 3:06 ` bug#20545: Transliterating curved to straight quotes in 8-bit environments Paul Eggert 0 siblings, 1 reply; 26+ messages in thread From: Eli Zaretskii @ 2015-05-17 19:04 UTC (permalink / raw) To: Paul Eggert; +Cc: 20545 > Date: Sun, 17 May 2015 09:58:52 -0700 > From: Paul Eggert <eggert@cs.ucla.edu> > CC: 20545@debbugs.gnu.org > > I'm not sure I'd worry about it. First, the kind of user likely to be running > multidisplay is not the kind of user likely to be starting up in an obsolescent > 8-bit locale. Second, if someone really does both things, they'll probably run > into other problems anyway. Third, this particular problem, for the rare user > who runs into it, will be just a minor glitch. I guess we can always wait and see if we get complaints about this ;-) ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#20545: Transliterating curved to straight quotes in 8-bit environments 2015-05-17 19:04 ` Eli Zaretskii @ 2015-06-01 3:06 ` Paul Eggert 2015-06-01 14:31 ` Eli Zaretskii 0 siblings, 1 reply; 26+ messages in thread From: Paul Eggert @ 2015-06-01 3:06 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 20545 [-- Attachment #1: Type: text/plain, Size: 874 bytes --] Eli Zaretskii wrote: > I guess we can always wait and see if we get complaints about this ;-) In trying out a few new things I did run into a problem in batch mode, because (print FOO) can generate improperly encoded output if FOO contains characters outside the system locale. For example, if the file t.el uses UTF-8 encoding and contains this: ;; -*- coding: utf-8 -*- (print "‘x’ “y” `z'") and Emacs is in an 8-bit locale, the command 'emacs --batch -l t.el' will output the string "‘x’ “y” `z'" to stdout in a UTF-8 encoding, which is an encoding error for this environment. Although this problem can occur with any non-ASCII character, diagnostics containing curved quotes will make it more likely. I installed the attached patch to fix this, using the same technique for standard output that Emacs is already using for standard display. [-- Attachment #2: 0001-Treat-batch-stdout-stderr-like-standard-display.patch --] [-- Type: text/x-patch, Size: 9035 bytes --] From a1e999c8395b8a8cc0259bcf672043d5302425be Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert@cs.ucla.edu> Date: Sun, 31 May 2015 20:04:05 -0700 Subject: [PATCH] Treat batch stdout/stderr like standard display Calls like (print FOO) could generate improperly encoded or hard-to-read output if FOO contains characters outside the system locale. Fix this by treating batch stdout and stderr like interactive standard display, when it comes to transliterating and encoding characters (Bug#20545). * doc/emacs/mule.texi (Communication Coding): * doc/lispref/display.texi (Active Display Table): * doc/lispref/nonascii.texi (Locales): * etc/NEWS: * src/coding.c (syms_of_coding): * src/dispnew.c (syms_of_display): Document this. * src/print.c: Include disptab.h. (printchar_to_stream): New function, with much of the guts of the old Fexternal_debugging_output, except this one also uses the standard display table. (printchar, strout, Fexternal_debugging_output): Use it. --- doc/emacs/mule.texi | 4 +- doc/lispref/display.texi | 5 ++- doc/lispref/nonascii.texi | 1 + etc/NEWS | 6 +++ src/coding.c | 3 +- src/dispnew.c | 1 + src/print.c | 106 ++++++++++++++++++++++++++++++++-------------- 7 files changed, 90 insertions(+), 36 deletions(-) diff --git a/doc/emacs/mule.texi b/doc/emacs/mule.texi index 7336fdc..80b1384 100644 --- a/doc/emacs/mule.texi +++ b/doc/emacs/mule.texi @@ -1164,7 +1164,9 @@ current language environment. to use when encoding and decoding system strings such as system error messages and @code{format-time-string} formats and time stamps. That coding system is also used for decoding non-@acronym{ASCII} keyboard -input on the X Window System. You should choose a coding system that is compatible +input on the X Window System and for encoding text sent to the +standard output and error streams when in batch mode. You should +choose a coding system that is compatible with the underlying system's text representation, which is normally specified by one of the environment variables @env{LC_ALL}, @env{LC_CTYPE}, and @env{LANG}. (The first one, in the order diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index b12995b..357a3c3 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -6522,8 +6522,9 @@ no buffer display table. @defvar standard-display-table The value of this variable is the standard display table, which is used when Emacs is displaying a buffer in a window with neither a -window display table nor a buffer display table defined. Its default -is @code{nil}. +window display table nor a buffer display table defined, or when Emacs +is outputting text to the standard output or error streams. Its +default is @code{nil}. @end defvar The @file{disp-table} library defines several functions for changing diff --git a/doc/lispref/nonascii.texi b/doc/lispref/nonascii.texi index f160184..362c3a4 100644 --- a/doc/lispref/nonascii.texi +++ b/doc/lispref/nonascii.texi @@ -1959,6 +1959,7 @@ how Emacs interacts with these features. @cindex keyboard input decoding on X This variable specifies the coding system to use for decoding system error messages and---on X Window system only---keyboard input, for +sending batch output to the standard output and error streams, for encoding the format argument to @code{format-time-string}, and for decoding the return value of @code{format-time-string}. @end defvar diff --git a/etc/NEWS b/etc/NEWS index d07057e..57e63b1 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -947,6 +947,12 @@ integers. ** New function `set-binary-mode' allows to switch a standard stream of the Emacs process to binary I/O mode. +** In locales that cannot display curved quotes, ASCII approximations +are installed in standard-display-table. + +** Standard output and error streams now transliterate characters via +standard-display-table, and encode output using locale-coding-system. + ** Miscellaneous name change For consistency with the usual Emacs spelling, the Lisp variable diff --git a/src/coding.c b/src/coding.c index 776ecac..9342c38 100644 --- a/src/coding.c +++ b/src/coding.c @@ -11121,7 +11121,8 @@ See also the function `find-operation-coding-system'. */); DEFVAR_LISP ("locale-coding-system", Vlocale_coding_system, doc: /* Coding system to use with system messages. -Also used for decoding keyboard input on X Window system. */); +Also used for decoding keyboard input on X Window system, and for +encoding standard output and error streams. */); Vlocale_coding_system = Qnil; /* The eol mnemonics are reset in startup.el system-dependently. */ diff --git a/src/dispnew.c b/src/dispnew.c index 693dd49..7e7afa7 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -6245,6 +6245,7 @@ Each element can be: DEFVAR_LISP ("standard-display-table", Vstandard_display_table, doc: /* Display table to use for buffers that specify none. +It is also used for standard output and error streams. See `buffer-display-table' for more information. */); Vstandard_display_table = Qnil; diff --git a/src/print.c b/src/print.c index a182839..65c120d 100644 --- a/src/print.c +++ b/src/print.c @@ -31,6 +31,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include "window.h" #include "process.h" #include "dispextern.h" +#include "disptab.h" #include "termchar.h" #include "intervals.h" #include "blockinput.h" @@ -195,6 +196,61 @@ print_unwind (Lisp_Object saved_text) memcpy (print_buffer, SDATA (saved_text), SCHARS (saved_text)); } +/* Print character CH to the stdio stream STREAM. */ + +static void +printchar_to_stream (unsigned int ch, FILE *stream) +{ + Lisp_Object dv IF_LINT (= Qnil); + ptrdiff_t i = 0, n = 1; + + if (CHAR_VALID_P (ch) && DISP_TABLE_P (Vstandard_display_table)) + { + dv = DISP_CHAR_VECTOR (XCHAR_TABLE (Vstandard_display_table), ch); + if (VECTORP (dv)) + { + n = ASIZE (dv); + goto next_char; + } + } + + while (true) + { + if (ASCII_CHAR_P (ch)) + { + putc (ch, stream); +#ifdef WINDOWSNT + /* Send the output to a debugger (nothing happens if there + isn't one). */ + if (print_output_debug_flag && stream == stderr) + OutputDebugString ((char []) {ch, '\0'}); +#endif + } + else + { + unsigned char mbstr[MAX_MULTIBYTE_LENGTH]; + int len = CHAR_STRING (ch, mbstr); + Lisp_Object encoded_ch = + ENCODE_SYSTEM (make_multibyte_string ((char *) mbstr, 1, len)); + + fwrite (SSDATA (encoded_ch), 1, SBYTES (encoded_ch), stream); +#ifdef WINDOWSNT + if (print_output_debug_flag && stream == stderr) + OutputDebugString (SSDATA (encoded_ch)); +#endif + } + + i++; + + next_char: + for (; i < n; i++) + if (CHARACTERP (AREF (dv, i))) + break; + if (! (i < n)) + break; + ch = XFASTINT (AREF (dv, i)); + } +} /* Print character CH using method FUN. FUN nil means print to print_buffer. FUN t means print to echo area or stdout if @@ -226,7 +282,10 @@ printchar (unsigned int ch, Lisp_Object fun) else if (noninteractive) { printchar_stdout_last = ch; - fwrite (str, 1, len, stdout); + if (DISP_TABLE_P (Vstandard_display_table)) + printchar_to_stream (ch, stdout); + else + fwrite (str, 1, len, stdout); noninteractive_need_newline = 1; } else @@ -267,7 +326,19 @@ strout (const char *ptr, ptrdiff_t size, ptrdiff_t size_byte, } else if (noninteractive && EQ (printcharfun, Qt)) { - fwrite (ptr, 1, size_byte, stdout); + if (DISP_TABLE_P (Vstandard_display_table)) + { + int len; + for (ptrdiff_t i = 0; i < size_byte; i += len) + { + int ch = STRING_CHAR_AND_LENGTH ((const unsigned char *) ptr + i, + len); + printchar_to_stream (ch, stdout); + } + } + else + fwrite (ptr, 1, size_byte, stdout); + noninteractive_need_newline = 1; } else if (EQ (printcharfun, Qt)) @@ -688,37 +759,8 @@ You can call print while debugging emacs, and pass it this function to make it write to the debugging output. */) (Lisp_Object character) { - unsigned int ch; - CHECK_NUMBER (character); - ch = XINT (character); - if (ASCII_CHAR_P (ch)) - { - putc (ch, stderr); -#ifdef WINDOWSNT - /* Send the output to a debugger (nothing happens if there isn't - one). */ - if (print_output_debug_flag) - { - char buf[2] = {(char) XINT (character), '\0'}; - OutputDebugString (buf); - } -#endif - } - else - { - unsigned char mbstr[MAX_MULTIBYTE_LENGTH]; - ptrdiff_t len = CHAR_STRING (ch, mbstr); - Lisp_Object encoded_ch = - ENCODE_SYSTEM (make_multibyte_string ((char *) mbstr, 1, len)); - - fwrite (SSDATA (encoded_ch), SBYTES (encoded_ch), 1, stderr); -#ifdef WINDOWSNT - if (print_output_debug_flag) - OutputDebugString (SSDATA (encoded_ch)); -#endif - } - + printchar_to_stream (XINT (character), stderr); return character; } -- 2.1.0 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* bug#20545: Transliterating curved to straight quotes in 8-bit environments 2015-06-01 3:06 ` bug#20545: Transliterating curved to straight quotes in 8-bit environments Paul Eggert @ 2015-06-01 14:31 ` Eli Zaretskii 0 siblings, 0 replies; 26+ messages in thread From: Eli Zaretskii @ 2015-06-01 14:31 UTC (permalink / raw) To: Paul Eggert; +Cc: 20545 > Date: Sun, 31 May 2015 20:06:16 -0700 > From: Paul Eggert <eggert@cs.ucla.edu> > CC: 20545@debbugs.gnu.org > > In trying out a few new things I did run into a problem in batch mode, because > (print FOO) can generate improperly encoded output if FOO contains characters > outside the system locale. For example, if the file t.el uses UTF-8 encoding > and contains this: > > ;; -*- coding: utf-8 -*- > (print "‘x’ “y” `z'") > > and Emacs is in an 8-bit locale, the command 'emacs --batch -l t.el' will output > the string "‘x’ “y” `z'" to stdout in a UTF-8 encoding, which is an encoding > error for this environment. > > Although this problem can occur with any non-ASCII character, diagnostics > containing curved quotes will make it more likely. I installed the attached > patch to fix this, using the same technique for standard output that Emacs is > already using for standard display. It sounds strange to use display tables for batch-mode output, but maybe it's just a matter of getting used to. ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Punct 2015-05-10 23:55 bug#20545: New minor mode Electric Punct Paul Eggert 2015-05-11 15:00 ` Eli Zaretskii @ 2015-05-11 15:57 ` Stefan Monnier 2015-05-13 7:33 ` Paul Eggert 2015-05-11 16:48 ` Artur Malabarba 2015-05-26 11:24 ` bug#20545: New minor mode Electric Quote Paul Eggert 3 siblings, 1 reply; 26+ messages in thread From: Stefan Monnier @ 2015-05-11 15:57 UTC (permalink / raw) To: Paul Eggert; +Cc: 20545 > Attached are two proposed patches. The first creates a new minor mode > Electric Punct that does a variant of "smart quoting" designed for the Emacs > tradition of using ` and ' as aliases for left and right single quotation > marks. How does it interact with electric-pair-mode? Stefan ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Punct 2015-05-11 15:57 ` bug#20545: New minor mode Electric Punct Stefan Monnier @ 2015-05-13 7:33 ` Paul Eggert 0 siblings, 0 replies; 26+ messages in thread From: Paul Eggert @ 2015-05-13 7:33 UTC (permalink / raw) To: Stefan Monnier; +Cc: 20545 Stefan Monnier wrote: > How does it interact with electric-pair-mode? Err, it doesn't. Thanks. I'll look into that. Your comment prompted me to find related issues with the patch I proposed in Bug#20385, and I just now sent in a revised version of that patch, here: http://bugs.gnu.org/20385#205 ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Punct 2015-05-10 23:55 bug#20545: New minor mode Electric Punct Paul Eggert 2015-05-11 15:00 ` Eli Zaretskii 2015-05-11 15:57 ` bug#20545: New minor mode Electric Punct Stefan Monnier @ 2015-05-11 16:48 ` Artur Malabarba 2015-05-26 11:24 ` bug#20545: New minor mode Electric Quote Paul Eggert 3 siblings, 0 replies; 26+ messages in thread From: Artur Malabarba @ 2015-05-11 16:48 UTC (permalink / raw) To: Paul Eggert; +Cc: 20545 Not to start bikeshedding here, but electric-punctuation sounds like something that automatically inserts spaces after punctionation marks, like comma and fullstop. ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Quote 2015-05-10 23:55 bug#20545: New minor mode Electric Punct Paul Eggert ` (2 preceding siblings ...) 2015-05-11 16:48 ` Artur Malabarba @ 2015-05-26 11:24 ` Paul Eggert 2015-05-27 14:24 ` Eli Zaretskii 3 siblings, 1 reply; 26+ messages in thread From: Paul Eggert @ 2015-05-26 11:24 UTC (permalink / raw) To: 20545; +Cc: Artur Malabarba [-- Attachment #1: Type: text/plain, Size: 700 bytes --] Attached is a revised patch that should address the comments raised: * The new minor mode is now disabled by default. * The patch doesn't affect .dir-locals.el. * The new minor mode is now (less ambitiously) called Electric Quote mode, not Electric Punct mode. * Electric Quote mode combines well with Electric Pair mode's pairings of ` and ', turning them into electric ‘ and ’. I did not implement the electric quote pairing of “ and ”, as it would be trickier to add and anyway any such pairing is considerably lower priority for Elisp. Plus another issue I found while testing: * Electric quoting is now inactive in buffers whose coding systems can't represent curved quotes. [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-New-minor-mode-Electric-Quote.patch --] [-- Type: text/x-patch; name="0001-New-minor-mode-Electric-Quote.patch", Size: 12395 bytes --] From f3f584027819837c26adc311a936e7a897c92f44 Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert@cs.ucla.edu> Date: Tue, 26 May 2015 03:53:50 -0700 Subject: [PATCH] New minor mode Electric Quote MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This lets you easily insert quotes ‘like this’ by typing quotes `like this', and similarly you can easily insert quotes “like this” by typing quotes ``like this'' (Bug#20545). * doc/emacs/basic.texi (Inserting Text): * doc/emacs/modes.texi (Minor Modes): * etc/NEWS: Document it. * doc/emacs/text.texi (Quotation Marks): New section. * lisp/electric.el (electric-quote-comment) (electric-quote-string, electric-quote-paragraph): New custom vars. (electric--insertable-p) (electric-quote-post-self-insert-function): New functions. (electric-quote-mode, electric-quote-local-mode): New minor modes. * lisp/progmodes/elisp-mode.el (emacs-lisp-mode): Add curved single quotes to electric-pair-text-pairs. Set electric-quote-string in this buffer. --- doc/emacs/basic.texi | 6 +++ doc/emacs/modes.texi | 9 ++++ doc/emacs/text.texi | 38 +++++++++++++++ etc/NEWS | 2 + lisp/electric.el | 109 +++++++++++++++++++++++++++++++++++++++++++ lisp/progmodes/elisp-mode.el | 3 +- 6 files changed, 166 insertions(+), 1 deletion(-) diff --git a/doc/emacs/basic.texi b/doc/emacs/basic.texi index be45856..cc9602e 100644 --- a/doc/emacs/basic.texi +++ b/doc/emacs/basic.texi @@ -127,6 +127,12 @@ sign (Unicode code-point @code{U+221E}): A numeric argument to @kbd{C-q} or @kbd{C-x 8 @key{RET}} specifies how many copies of the character to insert (@pxref{Arguments}). + In some contexts, if you type a quotation using grave accent and +apostrophe @t{`like this'}, it is converted to a form @t{‘like this’} +using single quotation marks. Similarly, typing a quotation @t{``like +this''} using double grave accent and apostrophe converts it to a form +@t{“like this”} using double quotation marks. @xref{Quotation Marks}. + @node Moving Point @section Changing the Location of Point diff --git a/doc/emacs/modes.texi b/doc/emacs/modes.texi index 0e8f46a..b4538db 100644 --- a/doc/emacs/modes.texi +++ b/doc/emacs/modes.texi @@ -200,6 +200,15 @@ Auto Save mode saves the buffer contents periodically to reduce the amount of work you can lose in case of a crash. @xref{Auto Save}. @item +@cindex Electric Quote mode +@cindex mode, Electric Quote +@findex electric-quote-mode +Electric Quote mode automatically converts quotation marks. For +example, it requotes text typed @t{`like this'} to text @t{‘like +this’}. You can control what kind of text it operates in, and you can +disable it entirely in individual buffers. @xref{Quotation Marks}. + +@item Enriched mode enables editing and saving of formatted text. @xref{Enriched Text}. diff --git a/doc/emacs/text.texi b/doc/emacs/text.texi index 9bc5ade..f243095 100644 --- a/doc/emacs/text.texi +++ b/doc/emacs/text.texi @@ -69,6 +69,7 @@ for editing such pictures. * Sentences:: Moving over and killing sentences. * Paragraphs:: Moving over paragraphs. * Pages:: Moving over pages. +* Quotation Marks:: Inserting quotation marks. * Filling:: Filling or justifying text. * Case:: Changing the case of text. * Text Mode:: The major modes for editing text files. @@ -404,6 +405,43 @@ that separates pages (@pxref{Regexps}). The normal value of this variable is @code{"^\f"}, which matches a formfeed character at the beginning of a line. +@node Quotation Marks +@section Quotation Marks +@cindex Quotation marks +@cindex Electric Quote mode +@cindex mode, Electric Quote + One common way to quote is the typewriter convention, which quotes +using straight apostrophes @t{'like this'} or double-quotes @t{"like +this"}. Another common way is the curved quote convention, which uses +left and right single or double quotation marks @t{‘like this’} or +@t{“like this”}. Typewriter quotes are simple and portable; curved +quotes are unambiguous and typically look nicer. + + Electric Quote mode makes it easier to type curved quotes. It +optionally converts a quotation's grave accent and apostrophe @t{`like +this'} to single quotation marks @t{‘like this’}. Similarly, it +converts a quotation's double grave accent and double apostrophe +@t{``like this''} to double quotation marks @t{“like this”}. These +conversions are suppressed in buffers whose coding systems cannot +represent curved quote characters. + + You can customize the behavior of Electric Quote mode by customizing +variables that control where it is active. It is active in text +paragraphs if @code{electric-quote-paragraph} is non-@code{nil}, in +programming-language comments if @code{electric-quote-comment} is +non-@code{nil}, and in programming-language strings if +@code{electric-quote-string} is non-@code{nil}. The default is +@code{nil} for @code{electric-quote-string} and @code{t} for the other +variables. + + Electric Quote mode is disabled by default. To toggle it, type +@kbd{M-x electric-quote-mode}. To toggle it in a single buffer, use +@kbd{M-x electric-quote-local-mode}. To suppress it for a single use, +type @kbd{C-q `} or @kbd{C-q '} instead of @kbd{`} or @kbd{'}. To +insert a curved quote even when Electric Quote is disabled or +inactive, use @kbd{C-x 8 @key{RET}} (@code{insert-char}). +@xref{Inserting Text}. + @node Filling @section Filling Text @cindex filling text diff --git a/etc/NEWS b/etc/NEWS index 1cccc31..3c0b2cf 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -226,6 +226,8 @@ successive char insertions. ** C-x 8 now has shorthands for these chars: ‐ ‑ ‒ – — ― ‘ ’ “ ” † ‡ • ′ ″ € № ← → ↔ − ≈ ≠ ≤ ≥. As before, you can type C-x 8 C-h to list shorthands. +** New minor mode electric-quote-mode for quoting ‘like this’ and “like this”. + ** New minor mode global-eldoc-mode is enabled by default. ** Emacs now supports "bracketed paste mode" when running on a terminal diff --git a/lisp/electric.el b/lisp/electric.el index dd7767f..a1fd6e9 100644 --- a/lisp/electric.el +++ b/lisp/electric.el @@ -413,6 +413,115 @@ The variable `electric-layout-rules' says when and how to insert newlines." (remove-hook 'post-self-insert-hook #'electric-layout-post-self-insert-function)))) +;;; Electric quoting. + +(defcustom electric-quote-comment t + "Non-nil means to use electric quoting in program comments." + :type 'boolean :safe 'booleanp :group 'electricity) + +(defcustom electric-quote-string nil + "Non-nil means to use electric quoting in program strings." + :type 'boolean :safe 'booleanp :group 'electricity) + +(defcustom electric-quote-paragraph t + "Non-nil means to use electric quoting in text paragraphs." + :type 'boolean :safe 'booleanp :group 'electricity) + +(defun electric--insertable-p (string) + (not (unencodable-char-position nil nil buffer-file-coding-system + nil string))) + +(defun electric-quote-post-self-insert-function () + "Function that ‘electric-quote-mode’ adds to ‘post-self-insert-hook’. +This requotes when a quoting key is typed." + ;; (check-coding-systems-region "‘’“”" nil (list buffer-file-coding-system))) + (when (and electric-quote-mode + (memq last-command-event '(?\' ?\`))) + (let ((start + (if comment-start + (when (or electric-quote-comment electric-quote-string) + (let ((syntax (syntax-ppss))) + (and (or (and electric-quote-comment (nth 4 syntax)) + (and electric-quote-string (nth 3 syntax))) + (nth 8 syntax)))) + (and electric-quote-paragraph + (derived-mode-p 'text-mode) + (or (eq last-command-event ?\`) + (save-excursion (backward-paragraph) (point))))))) + (when start + (save-excursion + (if (eq last-command-event ?\`) + (cond ((and (electric--insertable-p "“") + (re-search-backward "[`‘]`" (- (point) 2) t)) + (replace-match "“") + (when (and electric-pair-mode + (eq (cdr-safe + (assq ?‘ electric-pair-text-pairs)) + (char-after))) + (delete-char 1)) + (setq last-command-event ?“)) + ((and (electric--insertable-p "‘") + (search-backward "`" (1- (point)) t)) + (replace-match "‘") + (setq last-command-event ?‘))) + (let ((pos (point))) + (if (memq (char-before (1- (point))) '(?\' ?’)) + (when (and (search-backward "“" start t) + (eq pos (re-search-forward + "“\\(\\([^‘”]\\|‘[^‘’”]*’\\)*\\)['’]'" + pos t))) + (replace-match "“\\1”") + (setq last-command-event ?”)) + (when (and (search-backward "‘" start t) + (eq pos (re-search-forward + "‘\\([^’]*\\)'" pos t))) + (replace-match "‘\\1’") + (setq last-command-event ?’)))))))))) + +(put 'electric-quote-post-self-insert-function 'priority 10) + +;;;###autoload +(define-minor-mode electric-quote-mode + "Toggle on-the-fly requoting (Electric Quote mode). +With a prefix argument ARG, enable Electric Quote mode if +ARG is positive, and disable it otherwise. If called from Lisp, +enable the mode if ARG is omitted or nil. + +When enabled, this replaces \\=`foo bar' with ‘foo bar’ and replaces +\\=`\\=`foo bar'' with “foo bar” as you type. This occurs only in +comments, strings, and text paragraphs, and these are selectively +controlled with ‘electric-quote-comment’, +‘electric-quote-string’, and ‘electric-quote-paragraph’. + +This is a global minor mode. To toggle the mode in a single buffer, +use ‘electric-quote-local-mode’." + :global t :group 'electricity + :initialize 'custom-initialize-delay + :init-value nil + (if (not electric-quote-mode) + (unless (catch 'found + (dolist (buf (buffer-list)) + (with-current-buffer buf + (if electric-quote-mode (throw 'found t))))) + (remove-hook 'post-self-insert-hook + #'electric-quote-post-self-insert-function)) + (add-hook 'post-self-insert-hook + #'electric-quote-post-self-insert-function) + (electric--sort-post-self-insertion-hook))) + +;;;###autoload +(define-minor-mode electric-quote-local-mode + "Toggle ‘electric-quote-mode’ only in this buffer." + :variable (buffer-local-value 'electric-quote-mode (current-buffer)) + (cond + ((eq electric-quote-mode (default-value 'electric-quote-mode)) + (kill-local-variable 'electric-quote-mode)) + ((not (default-value 'electric-quote-mode)) + ;; Locally enabled, but globally disabled. + (electric-quote-mode 1) ; Setup the hooks. + (setq-default electric-quote-mode nil) ; But keep it globally disabled. + ))) + (provide 'electric) ;;; electric.el ends here diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index e06b920..22f66a9 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -231,7 +231,8 @@ Blank lines separate paragraphs. Semicolons start comments. (lisp-mode-variables nil nil 'elisp) (add-hook 'after-load-functions #'elisp--font-lock-flush-elisp-buffers) (setq-local electric-pair-text-pairs - (cons '(?\` . ?\') electric-pair-text-pairs)) + `((?‘ . ?’) (?\` . ?\') ,@electric-pair-text-pairs)) + (setq-local electric-quote-string t) (setq imenu-case-fold-search nil) (add-function :before-until (local 'eldoc-documentation-function) #'elisp-eldoc-documentation-function) -- 2.1.0 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Quote 2015-05-26 11:24 ` bug#20545: New minor mode Electric Quote Paul Eggert @ 2015-05-27 14:24 ` Eli Zaretskii 2015-05-27 15:27 ` Paul Eggert 0 siblings, 1 reply; 26+ messages in thread From: Eli Zaretskii @ 2015-05-27 14:24 UTC (permalink / raw) To: Paul Eggert; +Cc: 20545, bruce.connor.am > Date: Tue, 26 May 2015 04:24:12 -0700 > From: Paul Eggert <eggert@cs.ucla.edu> > CC: Eli Zaretskii <eliz@gnu.org>, > Stefan Monnier <monnier@iro.umontreal.ca>, > Artur Malabarba <bruce.connor.am@gmail.com> > > Attached is a revised patch that should address the comments raised: Thanks. Please allow me a comment about the documentation: > --- a/doc/emacs/modes.texi > +++ b/doc/emacs/modes.texi > @@ -200,6 +200,15 @@ Auto Save mode saves the buffer contents periodically to reduce the > amount of work you can lose in case of a crash. @xref{Auto Save}. > > @item > +@cindex Electric Quote mode > +@cindex mode, Electric Quote > +@findex electric-quote-mode > +Electric Quote mode automatically converts quotation marks. For > +example, it requotes text typed @t{`like this'} to text @t{‘like > +this’}. You can control what kind of text it operates in, and you can > +disable it entirely in individual buffers. @xref{Quotation Marks}. > [...] > --- a/doc/emacs/text.texi > +++ b/doc/emacs/text.texi > @@ -404,6 +405,43 @@ that separates pages (@pxref{Regexps}). The normal value of this > variable is @code{"^\f"}, which matches a formfeed character at the > beginning of a line. > > +@node Quotation Marks > +@section Quotation Marks > +@cindex Quotation marks > +@cindex Electric Quote mode > +@cindex mode, Electric Quote > + One common way to quote is the typewriter convention, which quotes As you see, you have identical index entries in 2 different places. That is generally not useful, because they get converted to something like "foo" and "foo <1>", and the reader will have no way of knowing which one does she want. In this case, I would simply drop the first set of entries (and move the "electric-quote-mode" one to the second set), to where the actual description of this mode lives. There's no need to index a place that just mentions the mode in passing and sends the reader to the real description. ^ permalink raw reply [flat|nested] 26+ messages in thread
* bug#20545: New minor mode Electric Quote 2015-05-27 14:24 ` Eli Zaretskii @ 2015-05-27 15:27 ` Paul Eggert 0 siblings, 0 replies; 26+ messages in thread From: Paul Eggert @ 2015-05-27 15:27 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 20545 [-- Attachment #1: Type: text/plain, Size: 187 bytes --] Thanks for the review. I'll fold in the attached further patch before installing. As you may be able to tell, I don't use the manual indexes and so my indexing can be a bit random. [-- Attachment #2: doc.txt --] [-- Type: text/plain, Size: 1599 bytes --] diff --git a/doc/emacs/modes.texi b/doc/emacs/modes.texi index b4538db..e79561a 100644 --- a/doc/emacs/modes.texi +++ b/doc/emacs/modes.texi @@ -200,9 +200,6 @@ Auto Save mode saves the buffer contents periodically to reduce the amount of work you can lose in case of a crash. @xref{Auto Save}. @item -@cindex Electric Quote mode -@cindex mode, Electric Quote -@findex electric-quote-mode Electric Quote mode automatically converts quotation marks. For example, it requotes text typed @t{`like this'} to text @t{‘like this’}. You can control what kind of text it operates in, and you can diff --git a/doc/emacs/text.texi b/doc/emacs/text.texi index f243095..0785026 100644 --- a/doc/emacs/text.texi +++ b/doc/emacs/text.texi @@ -410,6 +410,7 @@ beginning of a line. @cindex Quotation marks @cindex Electric Quote mode @cindex mode, Electric Quote +@findex electric-quote-mode One common way to quote is the typewriter convention, which quotes using straight apostrophes @t{'like this'} or double-quotes @t{"like this"}. Another common way is the curved quote convention, which uses @@ -425,6 +426,9 @@ converts a quotation's double grave accent and double apostrophe conversions are suppressed in buffers whose coding systems cannot represent curved quote characters. +@vindex electric-quote-paragraph +@vindex electric-quote-comment +@vindex electric-quote-string You can customize the behavior of Electric Quote mode by customizing variables that control where it is active. It is active in text paragraphs if @code{electric-quote-paragraph} is non-@code{nil}, in ^ permalink raw reply related [flat|nested] 26+ messages in thread
end of thread, other threads:[~2015-06-01 14:31 UTC | newest] Thread overview: 26+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-05-10 23:55 bug#20545: New minor mode Electric Punct Paul Eggert 2015-05-11 15:00 ` Eli Zaretskii 2015-05-13 7:48 ` Paul Eggert 2015-05-13 13:10 ` Stefan Monnier 2015-05-13 14:49 ` Paul Eggert 2015-05-13 17:05 ` Eli Zaretskii 2015-05-14 3:52 ` Stefan Monnier 2015-05-14 14:54 ` Eli Zaretskii 2015-05-13 16:54 ` Eli Zaretskii 2015-05-13 16:38 ` Eli Zaretskii 2015-05-13 16:56 ` Paul Eggert 2015-05-13 17:16 ` Eli Zaretskii 2015-05-13 18:10 ` Eli Zaretskii 2015-05-14 6:32 ` Paul Eggert 2015-05-16 21:20 ` Paul Eggert 2015-05-17 14:33 ` Eli Zaretskii 2015-05-17 16:58 ` Paul Eggert 2015-05-17 19:04 ` Eli Zaretskii 2015-06-01 3:06 ` bug#20545: Transliterating curved to straight quotes in 8-bit environments Paul Eggert 2015-06-01 14:31 ` Eli Zaretskii 2015-05-11 15:57 ` bug#20545: New minor mode Electric Punct Stefan Monnier 2015-05-13 7:33 ` Paul Eggert 2015-05-11 16:48 ` Artur Malabarba 2015-05-26 11:24 ` bug#20545: New minor mode Electric Quote Paul Eggert 2015-05-27 14:24 ` Eli Zaretskii 2015-05-27 15:27 ` Paul Eggert
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).