mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-15 10:30:25 -08:00
New minor mode Electric Quote
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.
This commit is contained in:
parent
4643f6c21a
commit
73512b8cff
6 changed files with 165 additions and 0 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -199,6 +199,12 @@ becoming too long. @xref{Filling}.
|
|||
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
|
||||
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}.
|
||||
|
|
|
|||
|
|
@ -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,47 @@ 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
|
||||
@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
|
||||
left and right single or double quotation marks @t{‘like this’} or
|
||||
@t{“like this”}. Typewriter quotes are simple and portable; curved
|
||||
quotes are less ambiguous 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.
|
||||
|
||||
@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
|
||||
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
|
||||
|
|
|
|||
2
etc/NEWS
2
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
|
||||
|
|
|
|||
108
lisp/electric.el
108
lisp/electric.el
|
|
@ -413,6 +413,114 @@ 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."
|
||||
(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
|
||||
|
|
|
|||
|
|
@ -232,6 +232,7 @@ Blank lines separate paragraphs. Semicolons start comments.
|
|||
(add-hook 'after-load-functions #'elisp--font-lock-flush-elisp-buffers)
|
||||
(setq-local electric-pair-text-pairs
|
||||
(append '((?\` . ?\') (?‘ . ?’)) 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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue