Smart quotes in Emacs 22|
Support for U+2018 and friends seems pretty widespread these days, so
I think it’s time for this:
;;; smart-quotes.el --- Smart Quotes mode for Emacs
;; Copyright (C) 2007 Gareth Rees
;; Author: Gareth Rees <firstname.lastname@example.org>
;; Created: 2007-10-20
;; Version: 1.0
;; Keywords: abbrev
;; Smart Quotes mode is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 2, or (at
;; your option) any later version.
;; In Smart Quotes minor mode, the ' and \" keys insert left and
;; right quotation marks according to the context around point.
(defcustom smart-quotes-left-context "\\s-\\|\\s(\\|^"
"Regular expression matching the context in which a left
quotation mark will be inserted (a right quotation mark will
be inserted in all other contexts)."
(defun smart-quotes-insert-single ()
"Insert U+2018 LEFT SINGLE QUOTATION MARK if point is preceded
by `smart-quotes-left-context'; U+2019 RIGHT SINGLE QUOTATION MARK
(ucs-insert (if (looking-back smart-quotes-left-context) #x2018 #x2019)))
(defun smart-quotes-insert-double ()
"Insert U+201C LEFT DOUBLE QUOTATION MARK if point is preceded
by `smart-quotes-left-context'; U+201D RIGHT DOUBLE QUOTATION MARK
(ucs-insert (if (looking-back smart-quotes-left-context) #x201C #x201D)))
"Toggle Smart Quotes mode in the current buffer.
With argument ARG, turn Smart Quotes mode on iff ARG is positive.
In Smart Quotes mode, the ' and \" keys insert left quotation
marks if point is preceded by text matching the option
`smart-quotes-left-context' and right quotation marks otherwise."
:lighter (:eval (string ? (decode-char 'ucs #x201C)
(decode-char 'ucs #x201D)))
:keymap '(("'" . smart-quotes-insert-single)
("\"" . smart-quotes-insert-double)))
looking-back are new in
Emacs 22. In later releases of Emacs 21 I think you can probably get
away with the following:
(defun ucs-insert (c)
"Insert the character whose Unicode code point is C."
(insert (decode-char 'ucs c)))
(defun looking-back (regexp)
"Return non-nil if text before point matches regular expression REGEXP."
(and (save-excursion (re-search-backward regexp nil t))
(= (match-end 0) (point))))
But if you’re editing text in a wide range of character sets, you
probably want to upgrade to Emacs 22 anyway, as there are lots of
improvements to international character support.