2026-10-26 Unicode punctuation in Emacs

I have a rather complicated relationship with non-ASCII punctuation. On the one hand, I like to keep my files (for example Org mode files) clean of Unicode stuff – especially emojis – with the obvious exception of Polish diacritical characters (“ąćęłńóśźżĄĆĘŁŃÓŚŹŻ”, if you are curious). On the other hand, I am a big fan of long dashes (though I very much prefer en-dashes to em-dashes); I also like using “proper” quotation marks.

I used to use Typopunct to enter these characters easily, but recently I tried to reduce my need for external packages. It turns out that Emacs already has support for half of what I need in the form of the Electric Quote mode.

The Electric Quote mode works somewhat different than Typopunct – the default way of entering the left and right quotes is by using ` and ' for single quotes and the same characters doubled for double ones. This is somewhat reminiscent of “classical” (pre-UTF-8) TeX, but it’s not something I’m accustomed to. I prefer to just type " and have Emacs replace it by the “correct” double quote. That’s easy enough:

(setopt electric-quote-replace-double t)
(setopt electric-quote-context-sensitive t) ; for single quotes

Since I don’t use single quotes very often, I don’t care about them as much, but making them work doesn’t cost much. (By the way, I can always say C-x 8 [, C-x 8 ], C-x 8 { and C-x 8 } to insert Unicode quotes, whether Electric Quote mode is on or not. Polish opening quotes are trickier – the Emacs manual doesn’t mention it, but they can be inserted using C-x 8 , ".) So, the only remaining problem is switching between Polish and English quotes. Like I mentioned a few months ago, my Org files sometimes contain both languages, so setting a language per file is not practical for me. When I used Typopunct, I had a simple function to switch languages, and it was bound to the same keybinding I used to toggle Typopunct, but with a prefix argument. That was a bit fiddly – with a prefix argument, it turned Typopunct on and switched the language, without it, it toggled the mode, and I never remembered the exact behavior. Let’s solve my problem with Electric Quote mode, but with a simpler semantic – instead of using a prefix argument, I’ll just make it a three-way toggle.

(require 'cl-lib)

(defvar mbork-electric-quote-language 'off
  "The language of electric quotes - `off', `en' or `pl'.")

(defun mbork-electric-quote-toggle ()
  "Toggle Electric Quote mode behavior.
This is a three-way toggle – the possible states are \"off\",
\"English\" and \"Polish\".  Note: only double quotes are influenced by
the language setting."
  (interactive)
  (cl-ecase mbork-electric-quote-language
    (off (electric-quote-mode 1)
         (setq electric-quote-chars '(?‘ ?’ ?“ ?”))
         (setq mbork-electric-quote-language 'en))
    (en (electric-quote-mode 1)
         (setq electric-quote-chars '(?‘ ?’ ?„ ?”))
         (setq mbork-electric-quote-language 'pl))
    (pl (electric-quote-mode -1)
        (setq mbork-electric-quote-language 'off)))
  (message "Electric quote mode set to %s"
           (cl-ecase mbork-electric-quote-language
             (off "off")
             (en "English")
             (pl "Polish"))))

One problem with this code is that the Polish opening quote does not work with the Electric Pair mode. This is easy to fix, even if that fix is not particularly elegant:

(push '(?„ . ?”) electric-pair-pairs)

The last thing I need to do is to bind mbork-electric-quote-toggle to some key. Since f8 is my prefix to various toggles, I figured that f8 " is the right choice:

(bind-key "<f8> \"" #'mbork-electric-quote-toggle)

(Actually, in my config it looks a bit different, since I have a transient installed on f8, but that is another story. That also allows me to make it repeating (via :transient t), so that f8 " " toggles twice etc. As I’ve written two weeks ago, it’s possible to do that without transient.)

Of course, that leaves the issue of en-dashes. This, however, is a non-issue for me, since my keyboard layout binds them on AltGr+- (that is, right alt and the hyphen).

And that’s it for today!

CategoryEnglish, CategoryBlog, CategoryEmacs, CategoryOrgMode