diff options
author | Philipp Stephani <phst@google.com> | 2017-06-28 23:47:57 +0200 |
---|---|---|
committer | Philipp Stephani <phst@google.com> | 2017-07-02 17:48:23 +0200 |
commit | 34d4720f833bb382b28d9faecf82d34db1eb4494 (patch) | |
tree | f149e3b03da94c7db458610007e82b33ac735018 /lisp/electric.el | |
parent | d90b98a2a52abf67b84aa12df282b0defec8505b (diff) | |
download | emacs-34d4720f833bb382b28d9faecf82d34db1eb4494.tar.gz |
Electric quotes: Improve support for Markdown mode (Bug#24709)
Introduce a new user option 'electric-quote-context-sensitive'. If
non-nil, have ' insert an opening quote if sensible.
Also introduce a new variable 'electric-quote-code-faces'. Major
modes such as 'markdown-mode' can add faces to this list to treat text
as inline code and disable electric quoting.
* lisp/electric.el (electric-quote-context-sensitive): New user
option.
(electric-quote-code-faces): New variable.
(electric-quote-post-self-insert-function): Treat ' as ` if
desired and applicable; disable electric quoting for given faces.
* test/lisp/electric-tests.el (electric-quote-opening-single)
(electric-quote-closing-single, electric-quote-opening-double)
(electric-quote-closing-double)
(electric-quote-context-sensitive-backtick)
(electric-quote-context-sensitive-bob-single)
(electric-quote-context-sensitive-bob-double)
(electric-quote-context-sensitive-bol-single)
(electric-quote-context-sensitive-bol-double)
(electric-quote-context-sensitive-after-space-single)
(electric-quote-context-sensitive-after-space-double)
(electric-quote-context-sensitive-after-letter-single)
(electric-quote-context-sensitive-after-letter-double)
(electric-quote-context-sensitive-after-paren-single)
(electric-quote-context-sensitive-after-paren-double)
(electric-quote-markdown-in-text)
(electric-quote-markdown-in-code): New unit tests.
Diffstat (limited to 'lisp/electric.el')
-rw-r--r-- | lisp/electric.el | 66 |
1 files changed, 47 insertions, 19 deletions
diff --git a/lisp/electric.el b/lisp/electric.el index 4078ef8193e..1564df5949c 100644 --- a/lisp/electric.el +++ b/lisp/electric.el @@ -443,11 +443,24 @@ quote, left double quote, and right double quote, respectively." :version "25.1" :type 'boolean :safe 'booleanp :group 'electricity) +(defcustom electric-quote-context-sensitive nil + "Non-nil means to replace \\=' with an electric quote depending on context. +If `electric-quote-context-sensitive' is non-nil, Emacs replaces +\\=' and \\='\\=' with an opening quote after a line break, +whitespace, opening parenthesis, or quote and leaves \\=` alone." + :version "26.1" + :type 'boolean :safe #'booleanp :group 'electricity) + +(defvar electric-quote-code-faces () + "List of faces to treat as inline code in `text-mode'.") + (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." (when (and electric-quote-mode - (memq last-command-event '(?\' ?\`))) + (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) @@ -462,30 +475,45 @@ This requotes when a quoting key is typed." (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 - (if (eq last-command-event ?\`) - (cond ((search-backward (string q< ?`) (- (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 "`" (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>))))))))))) + (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) |