From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Paul Eggert Newsgroups: gmane.emacs.bugs Subject: bug#20545: New minor mode Electric Punct Date: Sun, 10 May 2015 16:55:42 -0700 Organization: UCLA Computer Science Department Message-ID: <554FEFFE.7000303@cs.ucla.edu> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------040401050304070802020801" X-Trace: ger.gmane.org 1431302253 23253 80.91.229.3 (10 May 2015 23:57:33 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 10 May 2015 23:57:33 +0000 (UTC) To: 20545@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Mon May 11 01:57:22 2015 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Yrb5x-0006vr-6B for geb-bug-gnu-emacs@m.gmane.org; Mon, 11 May 2015 01:57:17 +0200 Original-Received: from localhost ([::1]:34976 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yrb5w-0005TE-C4 for geb-bug-gnu-emacs@m.gmane.org; Sun, 10 May 2015 19:57:16 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:53462) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yrb5q-0005Su-04 for bug-gnu-emacs@gnu.org; Sun, 10 May 2015 19:57:12 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Yrb5j-0003a1-DK for bug-gnu-emacs@gnu.org; Sun, 10 May 2015 19:57:09 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:58569) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yrb5j-0003Zx-9J for bug-gnu-emacs@gnu.org; Sun, 10 May 2015 19:57:03 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.80) (envelope-from ) id 1Yrb5i-0007B9-W4 for bug-gnu-emacs@gnu.org; Sun, 10 May 2015 19:57:03 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 10 May 2015 23:57:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 20545 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: X-Debbugs-Original-To: Emacs bug reports and feature requests Original-Received: via spool by submit@debbugs.gnu.org id=B.143130217327524 (code B ref -1); Sun, 10 May 2015 23:57:02 +0000 Original-Received: (at submit) by debbugs.gnu.org; 10 May 2015 23:56:13 +0000 Original-Received: from localhost ([127.0.0.1]:40308 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Yrb4t-00079q-4e for submit@debbugs.gnu.org; Sun, 10 May 2015 19:56:12 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:39644) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Yrb4p-00079W-Re for submit@debbugs.gnu.org; Sun, 10 May 2015 19:56:09 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Yrb4i-0003LN-FD for submit@debbugs.gnu.org; Sun, 10 May 2015 19:56:02 -0400 Original-Received: from lists.gnu.org ([2001:4830:134:3::11]:35518) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yrb4i-0003LJ-CC for submit@debbugs.gnu.org; Sun, 10 May 2015 19:56:00 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:53150) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yrb4g-0005Ow-7W for bug-gnu-emacs@gnu.org; Sun, 10 May 2015 19:56:00 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Yrb4c-0003Kf-2N for bug-gnu-emacs@gnu.org; Sun, 10 May 2015 19:55:58 -0400 Original-Received: from smtp.cs.ucla.edu ([131.179.128.62]:51411) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yrb4b-0003J4-Kd for bug-gnu-emacs@gnu.org; Sun, 10 May 2015 19:55:53 -0400 Original-Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 8E216A60002 for ; Sun, 10 May 2015 16:55:44 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Original-Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id qSRnn7CcnieT for ; Sun, 10 May 2015 16:55:43 -0700 (PDT) Original-Received: from [192.168.1.9] (pool-100-32-155-148.lsanca.fios.verizon.net [100.32.155.148]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 2875B39E801E for ; Sun, 10 May 2015 16:55:43 -0700 (PDT) User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:102643 Archived-At: This is a multi-part message in MIME format. --------------040401050304070802020801 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable Attached are two proposed patches. The first creates a new minor mode El= ectric=20 Punct that does a variant of "smart quoting" designed for the Emacs tradi= tion of=20 using ` and ' as aliases for left and right single quotation marks. This= new=20 minor mode is inactive by default, but the user can enable it in certain=20 contexts. The second patch modifies .dir-locals.el to enable the minor m= ode in=20 contexts where it should be useful when editing Emacs itself. These patches are related to Bug#20385 in that they make it much easier t= o edit=20 doc strings formatted =E2=80=98like this=E2=80=99, which is the point of = Bug#20385. (All that=20 one needs to do is to type the string "`like this'".) However, the main = idea of=20 this patch is independent of the Emacs doc string issue, as Emacs should = make it=20 easy to quote =E2=80=98like this=E2=80=99 when the user prefers this form= . I named this mode "Electric Punct" because I anticipate that there may be= a=20 similar need to enter em and en dashes, and a few other non-ASCII punctua= tion=20 marks commonly used in text. Quotes are a good place to start, so that's= where=20 I started. --------------040401050304070802020801 Content-Type: text/x-patch; name="0001-New-minor-mode-Electric-Punct.patch" Content-Disposition: attachment; filename="0001-New-minor-mode-Electric-Punct.patch" Content-Transfer-Encoding: quoted-printable >From 106bdf81a5d27e6b055da002f8f000614268a8a1 Mon Sep 17 00:00:00 2001 From: Paul Eggert 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}). =20 + In some contexts, if you type a quotation using grave accent and +apostrophe @samp{`like this'}, it is converted to a form @samp{=E2=80=98= like +this=E2=80=99} using single quotation marks. Similarly, typing a quotat= ion +@samp{``like this''} using double grave accent and apostrophe converts +it to a form @samp{=E2=80=9Clike this=E2=80=9D} using double quotation m= arks. +@xref{Punctuation}. + @node Moving Point @section Changing the Location of Point =20 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 periodicall= y to reduce the amount of work you can lose in case of a crash. @xref{Auto Save}. =20 @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{=E2=80=98= like +this=E2=80=99}. You can control what kind of text it operates in, and y= ou can +disable it entirely in individual buffers. @xref{Punctuation}. + +@item Enriched mode enables editing and saving of formatted text. @xref{Enriched Text}. =20 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. =20 +@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{=E2=80=98like thi= s=E2=80=99} or +@samp{=E2=80=9Clike this=E2=80=9D}. Typewriter quotes are simple and po= rtable; 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{=E2=80=98= like +this=E2=80=99}. Similarly, it converts a quotation using double grave a= ccent +and double apostrophe @samp{``like this''} to a form using double +quotation marks @samp{=E2=80=9Clike this=E2=80=9D}. + + 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. =20 ** Unicode names entered via C-x 8 RET now use substring completion by d= efault. =20 -** New minor mode global-eldoc-mode is enabled by default. +** New minor modes electric-punct-mode and global-eldoc-mode +are enabled by default. =20 ** 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 h= ow to insert newlines." (remove-hook 'post-self-insert-hook #'electric-layout-post-self-insert-function)))) =20 +;;; 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 =E2=80=98electric-punct-mode=E2=80=99 adds to =E2=80=98= post-self-insert-hook=E2=80=99. +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 "[`=E2=80=98]`" (- (point) 2) t= ) + (replace-match "=E2=80=9C")) + ((search-backward "`" (1- (point)) t) + (replace-match "=E2=80=98"))) + (let ((pos (point))) + (if (memq (char-before (1- (point))) '(?' ?=E2=80=99)) + (when (and (search-backward "=E2=80=9C" start t) + (eq pos (re-search-forward + "=E2=80=9C\\([^=E2=80=9D]*\\)['=E2= =80=99]'" pos t))) + (replace-match "=E2=80=9C\\1=E2=80=9D")) + (when (and (search-backward "=E2=80=98" start t) + (eq pos (re-search-forward + "=E2=80=98\\([^=E2=80=99]*\\)'" pos = t))) + (replace-match "=E2=80=98\\1=E2=80=99")))))))))) + +(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 =E2=80=98foo bar=E2=80=99 and= replaces +``foo bar'' with =E2=80=9Cfoo bar=E2=80=9D as you type. This occurs onl= y in +comments, strings, and text paragraphs, and these are selectively +controlled with =E2=80=98electric-punct-comment=E2=80=99, +=E2=80=98electric-punct-string=E2=80=99, and =E2=80=98electric-punct-par= agraph=E2=80=99. + +This is a global minor mode. To toggle the mode in a single buffer, +use =E2=80=98electric-punct-local-mode=E2=80=99." + :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 =E2=80=98electric-punct-mode=E2=80=99 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 disabl= ed. + ))) + (provide 'electric) =20 ;;; electric.el ends here --=20 2.1.0 --------------040401050304070802020801 Content-Type: text/x-patch; name="0002-Use-Electric-Punct-when-editing-Emacs-source.patch" Content-Disposition: attachment; filename="0002-Use-Electric-Punct-when-editing-Emacs-source.patch" Content-Transfer-Encoding: quoted-printable >From 401bf3e899ac84d062c86da469c33c662f969ef8 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 10 May 2015 16:07:13 -0700 Subject: [PROPOSED PATCH 2/2] Use Electric Punct when editing Emacs sourc= e MIME-Version: 1.0 Content-Type: text/plain; charset=3DUTF-8 Content-Transfer-Encoding: 8bit This is a companion to the patch proposed in Bug#20385. The idea is to let maintainers quote =E2=80=98like this=E2=80=99 in doc s= trings 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)))) --=20 2.1.0 --------------040401050304070802020801--