From: Philipp Stephani <p.stephani2@gmail.com>
To: 24709@debbugs.gnu.org
Subject: bug#24709: 26.0.50; Support for Markdown in electric-quote-mode
Date: Sun, 02 Jul 2017 16:20:00 +0000 [thread overview]
Message-ID: <CAArVCkSGf4VxjuCQXEbDTz0DFJYwr4nB6EyhEM=67n+xbd5RZA@mail.gmail.com> (raw)
In-Reply-To: <CAArVCkSzvx5Eqk2ApfWbHufSsmqbonBzJp+U+86PbEnuWdkJEw@mail.gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 1343 bytes --]
Philipp Stephani <p.stephani2@gmail.com> schrieb am So., 2. Juli 2017 um
17:49 Uhr:
> Philipp Stephani <p.stephani2@gmail.com> schrieb am Mi., 28. Juni 2017 um
> 23:59 Uhr:
>
>> Philipp Stephani <p.stephani2@gmail.com> schrieb am So., 16. Okt. 2016
>> um 19:22 Uhr:
>>
>>>
>>> When editing a Markdown document with electric-quote-mode enabled, the
>>> experience is not optimal because ` (backtick) in Markdown is a syntax
>>> element (for introducing code spans and blocks), but is converted by
>>> electric-quote-mode. Also ` and ' inside code spans and blocks continue
>>> to insert curly quotes where they shouldn't. I propose the following:
>>>
>>> - Provide an alternative behavior of electric-quote-mode where ` doesn't
>>> trigger replacement and ' can insert left or right curly quotes,
>>> depending on whether it follows a space or similar (newline, beginning
>>> of buffer, opening parenthesis).
>>>
>>> - Provide a way to disable electric-quote-mode for certain regions,
>>> effectively the inverse of the existing electric-quote-string etc.
>>> This could be in the form of syntactic elements or text properties.
>>>
>>>
>>>
>> I've attached a patch. It doesn't cover all cases, though; e.g. an
>> unterminated Markdown code span is not supported yet.
>>
>
> Pushed as 34d4720f83.
>
Here are a couple more patches.
[-- Attachment #1.2: Type: text/html, Size: 2306 bytes --]
[-- Attachment #2: 0001-Refactor-electric-quote-mode.txt --]
[-- Type: text/plain, Size: 6763 bytes --]
From 7d9439e3096a37ba381a9fd03d63d1b5fcf4683a Mon Sep 17 00:00:00 2001
From: Philipp Stephani <phst@google.com>
Date: Sun, 2 Jul 2017 18:03:06 +0200
Subject: [PATCH 1/3] Refactor 'electric-quote-mode'
* lisp/electric.el (electric-quote-post-self-insert-function): Remove
local variable 'start', which was misnamed and only used once.
---
lisp/electric.el | 106 +++++++++++++++++++++++++++----------------------------
1 file changed, 52 insertions(+), 54 deletions(-)
diff --git a/lisp/electric.el b/lisp/electric.el
index 1564df5949..103f378ed3 100644
--- a/lisp/electric.el
+++ b/lisp/electric.el
@@ -460,60 +460,58 @@ electric-quote-post-self-insert-function
(when (and electric-quote-mode
(or (eq last-command-event ?\')
(and (not electric-quote-context-sensitive)
- (eq last-command-event ?\`))))
- (let ((start
- (if (and comment-start comment-use-syntax)
- (when (or electric-quote-comment electric-quote-string)
- (let* ((syntax (syntax-ppss))
- (beg (nth 8 syntax)))
- (and beg
- (or (and electric-quote-comment (nth 4 syntax))
- (and electric-quote-string (nth 3 syntax)))
- ;; Do not requote a quote that starts or ends
- ;; a comment or string.
- (eq beg (nth 8 (save-excursion
- (syntax-ppss (1- (point)))))))))
- (and electric-quote-paragraph
- (derived-mode-p 'text-mode)
- ;; FIXME: There should be a ‘cl-disjoint’ function.
- (null (cl-intersection (face-at-point nil 'multiple)
- electric-quote-code-faces
- :test #'eq))
- ;; FIXME: Why is the next form there? It’s never
- ;; nil.
- (or (eq last-command-event ?\`)
- (save-excursion (backward-paragraph) (point)))))))
- (pcase electric-quote-chars
- (`(,q< ,q> ,q<< ,q>>)
- (when start
- (save-excursion
- (let ((backtick ?\`))
- (if (or (eq last-command-event ?\`)
- (and electric-quote-context-sensitive
- (save-excursion
- (backward-char)
- (or (bobp) (bolp)
- (memq (char-before) (list q< q<<))
- (memq (char-syntax (char-before))
- '(?\s ?\())))
- (setq backtick ?\')))
- (cond ((search-backward (string q< backtick) (- (point) 2) t)
- (replace-match (string q<<))
- (when (and electric-pair-mode
- (eq (cdr-safe
- (assq q< electric-pair-text-pairs))
- (char-after)))
- (delete-char 1))
- (setq last-command-event q<<))
- ((search-backward (string backtick) (1- (point)) t)
- (replace-match (string q<))
- (setq last-command-event q<)))
- (cond ((search-backward (string q> ?') (- (point) 2) t)
- (replace-match (string q>>))
- (setq last-command-event q>>))
- ((search-backward "'" (1- (point)) t)
- (replace-match (string q>))
- (setq last-command-event q>))))))))))))
+ (eq last-command-event ?\`)))
+ (if (and comment-start comment-use-syntax)
+ (when (or electric-quote-comment electric-quote-string)
+ (let* ((syntax (syntax-ppss))
+ (beg (nth 8 syntax)))
+ (and beg
+ (or (and electric-quote-comment (nth 4 syntax))
+ (and electric-quote-string (nth 3 syntax)))
+ ;; Do not requote a quote that starts or ends
+ ;; a comment or string.
+ (eq beg (nth 8 (save-excursion
+ (syntax-ppss (1- (point)))))))))
+ (and electric-quote-paragraph
+ (derived-mode-p 'text-mode)
+ ;; FIXME: There should be a ‘cl-disjoint’ function.
+ (null (cl-intersection (face-at-point nil 'multiple)
+ electric-quote-code-faces
+ :test #'eq))
+ ;; FIXME: Why is the next form there? It’s never
+ ;; nil.
+ (or (eq last-command-event ?\`)
+ (save-excursion (backward-paragraph) (point))))))
+ (pcase electric-quote-chars
+ (`(,q< ,q> ,q<< ,q>>)
+ (save-excursion
+ (let ((backtick ?\`))
+ (if (or (eq last-command-event ?\`)
+ (and electric-quote-context-sensitive
+ (save-excursion
+ (backward-char)
+ (or (bobp) (bolp)
+ (memq (char-before) (list q< q<<))
+ (memq (char-syntax (char-before))
+ '(?\s ?\())))
+ (setq backtick ?\')))
+ (cond ((search-backward (string q< backtick) (- (point) 2) t)
+ (replace-match (string q<<))
+ (when (and electric-pair-mode
+ (eq (cdr-safe
+ (assq q< electric-pair-text-pairs))
+ (char-after)))
+ (delete-char 1))
+ (setq last-command-event q<<))
+ ((search-backward (string backtick) (1- (point)) t)
+ (replace-match (string q<))
+ (setq last-command-event q<)))
+ (cond ((search-backward (string q> ?') (- (point) 2) t)
+ (replace-match (string q>>))
+ (setq last-command-event q>>))
+ ((search-backward "'" (1- (point)) t)
+ (replace-match (string q>))
+ (setq last-command-event q>))))))))))
(put 'electric-quote-post-self-insert-function 'priority 10)
--
2.13.2
[-- Attachment #3: 0003-Further-improve-electric-quote-support-for-Markdown-Bu.txt --]
[-- Type: text/plain, Size: 4844 bytes --]
From 1a4d0ada2450f22246ad22d25e7c15d8da3c5249 Mon Sep 17 00:00:00 2001
From: Philipp Stephani <phst@google.com>
Date: Sun, 2 Jul 2017 18:14:21 +0200
Subject: [PATCH 3/3] Further improve electric quote support for Markdown
(Bug#24709)
Markdown sets both 'comment-start' and 'comment-use-syntax' to non-nil
values. Therefore 'electric-quote-mode' recognized it as a
programming mode. Fix this by first checking whether the current
major mode is derived from 'text-mode'.
* lisp/electric.el (electric-quote-post-self-insert-function): Treat
'text-mode' as stronger signal than comment syntax.
* test/lisp/electric-tests.el (electric-quote-markdown-in-text)
(electric-quote-markdown-in-code): Adapt unit tests.
---
lisp/electric.el | 34 +++++++++++++++++-----------------
test/lisp/electric-tests.el | 8 ++++++--
2 files changed, 23 insertions(+), 19 deletions(-)
diff --git a/lisp/electric.el b/lisp/electric.el
index a1e9079cb1..c335ae5d72 100644
--- a/lisp/electric.el
+++ b/lisp/electric.el
@@ -461,23 +461,23 @@ electric-quote-post-self-insert-function
(or (eq last-command-event ?\')
(and (not electric-quote-context-sensitive)
(eq last-command-event ?\`)))
- (if (and comment-start comment-use-syntax)
- (when (or electric-quote-comment electric-quote-string)
- (let* ((syntax (syntax-ppss))
- (beg (nth 8 syntax)))
- (and beg
- (or (and electric-quote-comment (nth 4 syntax))
- (and electric-quote-string (nth 3 syntax)))
- ;; Do not requote a quote that starts or ends
- ;; a comment or string.
- (eq beg (nth 8 (save-excursion
- (syntax-ppss (1- (point)))))))))
- (and electric-quote-paragraph
- (derived-mode-p 'text-mode)
- ;; FIXME: There should be a ‘cl-disjoint’ function.
- (null (cl-intersection (face-at-point nil 'multiple)
- electric-quote-code-faces
- :test #'eq)))))
+ (if (derived-mode-p 'text-mode)
+ (and electric-quote-paragraph
+ ;; FIXME: There should be a ‘cl-disjoint’ function.
+ (null (cl-intersection (face-at-point nil 'multiple)
+ electric-quote-code-faces
+ :test #'eq)))
+ (and comment-start comment-use-syntax
+ (or electric-quote-comment electric-quote-string)
+ (let* ((syntax (syntax-ppss))
+ (beg (nth 8 syntax)))
+ (and beg
+ (or (and electric-quote-comment (nth 4 syntax))
+ (and electric-quote-string (nth 3 syntax)))
+ ;; Do not requote a quote that starts or ends
+ ;; a comment or string.
+ (eq beg (nth 8 (save-excursion
+ (syntax-ppss (1- (point)))))))))))
(pcase electric-quote-chars
(`(,q< ,q> ,q<< ,q>>)
(save-excursion
diff --git a/test/lisp/electric-tests.el b/test/lisp/electric-tests.el
index 6f63d30e75..4212198b0a 100644
--- a/test/lisp/electric-tests.el
+++ b/test/lisp/electric-tests.el
@@ -694,11 +694,14 @@ electric-quote-context-sensitive-after-paren-double
:bindings '((electric-quote-context-sensitive . t))
:test-in-comments nil :test-in-strings nil)
+;; Simulate ‘markdown-mode’: it sets both ‘comment-start’ and
+;; ‘comment-use-syntax’, but derives from ‘text-mode’.
(define-electric-pair-test electric-quote-markdown-in-text
"" "'" :expected-string "’" :expected-point 2
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
- :bindings '((electric-quote-code-faces font-lock-constant-face))
+ :bindings '((electric-quote-code-faces font-lock-constant-face)
+ (comment-start "<!--") (comment-use-syntax t))
:test-in-comments nil :test-in-strings nil)
(define-electric-pair-test electric-quote-markdown-in-code
@@ -706,7 +709,8 @@ electric-quote-markdown-in-code
:expected-string "`'a`" :expected-point 3
:modes '(text-mode)
:fixture-fn #'electric-quote-local-mode
- :bindings '((electric-quote-code-faces font-lock-constant-face))
+ :bindings '((electric-quote-code-faces font-lock-constant-face)
+ (comment-start "<!--") (comment-use-syntax t))
:test-in-comments nil :test-in-strings nil)
(provide 'electric-tests)
--
2.13.2
[-- Attachment #4: 0002-Remove-pointless-code-in-electric-quote-mode.txt --]
[-- Type: text/plain, Size: 1245 bytes --]
From 0acddd26f1bdb9b08dea9812af2883925e023557 Mon Sep 17 00:00:00 2001
From: Philipp Stephani <phst@google.com>
Date: Sun, 2 Jul 2017 18:04:38 +0200
Subject: [PATCH 2/3] Remove pointless code in 'electric-quote-mode'
* lisp/electric.el (electric-quote-post-self-insert-function): Remove
pointless form.
---
lisp/electric.el | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/lisp/electric.el b/lisp/electric.el
index 103f378ed3..a1e9079cb1 100644
--- a/lisp/electric.el
+++ b/lisp/electric.el
@@ -477,11 +477,7 @@ electric-quote-post-self-insert-function
;; FIXME: There should be a ‘cl-disjoint’ function.
(null (cl-intersection (face-at-point nil 'multiple)
electric-quote-code-faces
- :test #'eq))
- ;; FIXME: Why is the next form there? It’s never
- ;; nil.
- (or (eq last-command-event ?\`)
- (save-excursion (backward-paragraph) (point))))))
+ :test #'eq)))))
(pcase electric-quote-chars
(`(,q< ,q> ,q<< ,q>>)
(save-excursion
--
2.13.2
next prev parent reply other threads:[~2017-07-02 16:20 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-16 17:19 bug#24709: 26.0.50; Support for Markdown in electric-quote-mode Philipp Stephani
2016-10-19 11:10 ` Alan Third
2017-06-28 21:59 ` Philipp Stephani
2017-07-02 15:49 ` Philipp Stephani
2017-07-02 16:20 ` Philipp Stephani [this message]
2017-07-09 19:57 ` Philipp Stephani
2017-07-14 12:36 ` Paul Eggert
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAArVCkSGf4VxjuCQXEbDTz0DFJYwr4nB6EyhEM=67n+xbd5RZA@mail.gmail.com' \
--to=p.stephani2@gmail.com \
--cc=24709@debbugs.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.