Chad Perrin: SOB

25 January 2009

entering special characters in Xorg

Filed under: Geek,Writing — apotheon @ 11:49

In MS Windows, if you hold down the rAlt key while typing 0164 on your keyboard’s number pad, then release the rAlt key, you’ll get the ¤ character. People sometimes miss that capability on Unix-like systems (read: Linux or *BSD). There’s a solution to the problem, however: the compose key.

The keyboard section in my xorg.conf file looks something like this:

Section "InputDevice"
       Identifier  "Keyboard0"
       Driver      "kbd"
       Option      "XkbOptions"  "compose:ralt"

That line that starts Option sets the rAlt key as my compose key. With that I can produce any of a dizzying array of digraphs and other special characters that don’t actually appear on my keyboard in just about any application in my X session. For instance, to produce that ¤ character, I would use the following key combination:

<rAlt>x o

In other words, I would hold down the Alt key to the right of my spacebar, press the x key, then release the Alt key, and finally press the o key. Thus, holding down the compose key (set to rAlt) for the first character of a combination of characters like xo produces a non-keyboard character like ¤. Similarly, I can use "A for Ä, "o for ö, ~n for ñ, oo for °, and ss for ß.

This, to me, seems like an improvement over the MS Windows way of doing it. The key combinations used are more mnemonically effective than simply trying to remember hundreds of numeric values. They’re also more “discoverable”, in that after learning a few one might begin to recognize patterns that allow one to accurately guess at combinations one doesn’t yet have memorized.

(edit: The following notes about setxkbmap and .xinitrc were added on Thursday, 7 October, 2010.)

If you are using a more recent version of, it is entirely possible your system is working fine without any xorg.conf file at all. You can use the setxkbmap command to specify a compose key instead:

setxkbmap -option compose:ralt

If you use startx to start your X session, you can use the .xinitrc file in your user account’s home directory to automatically execute this every time X is started. To do so, just add that command to the file before the line that specifies which window manager to fire up. You just need to add an ampersand at the end of the line.

The following is an example of the contents of an .xinitrc file — actually, the contents of my .xinitrc file at present:

xbattbar -at 1 top &
setxkbmap -option compose:ralt &
exec ahwm

The first line gives me a nifty line across the top of my screen that tells me how the laptop’s battery is doing. The last line tells X to use a window manager called AHWM.

A complete listing of default compose key sequences can be found in a file called Compose somewhere on most Unix-like systems. On FreeBSD, it should be located in a subdirectory of:


The subdirectory corresponds to the character set used in your user environment. On my laptop, I’m using the US English UTF-8 character set; that information is stored in the LANG variable:

> printenv LANG

Thus, my default compose key sequences are defined in:


Your mileage may vary.

This kind of thing is increasingly useful to me, especially since I’ve been using diereses more often when spelling out words where tonal shifts are not necessarily obvious from spelling, as in the cases of coöperation and naïve. The occasional desire for other special characters, such as ¥ or ñ, also rears its ugly head when writing speculative fiction or making a point about economics (for instance) — and not always in a context where HTML entities (e.g., &ntilde; for ñ) can be used.


  1. Why on earth are you using MM_CHARSET? Are you using something like (n)mh or MetaMail? The preferable and standardized (through POSIX and the likes) variable is LANG or LC_CTYPE/LC_ALL.

    Comment by J. Ruigrok van der Werven — 26 January 2009 @ 01:35

  2. Actually, I am using the LANG variable — as well as MM_CHARSET. I typed printenv | grep UTF and copied/pasted the first thing that came up into this SOB entry, which happened to be MM_CHARSET. I was having a braindead moment, probably because I was typing this up mere moments before going to bed. The MM_CHARSET variable is left over from a long time ago when I actually did have metamail set up (I don’t any longer, but the environment variable remains).

    Thanks for pointing out that I should have mentioned the LANG variable instead. I edited the original SOB entry above to reflect the use of the LANG environment variable.

    By the way, I tend to guess you probably came here from reddit — since that’s the only place I know of from which I’m getting much new traffic to this SOB entry. Underscores here are treated the same way they are in reddit comments, which is to say that they’re syntactically significant because I use Markdown syntax for formatting. I edited your comment by adding backticks around your use of environment variables so they’d all appear as written, rather than those with underscores being interpreted by the Markdown parser as indicating that italics should be started or stopped at the placement of an underscore.

    Comment by apotheon — 26 January 2009 @ 10:33

  3. That is awesome!

    Thanks so much for sharing.

    Comment by Alex — 30 January 2009 @ 02:39

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

All original content Copyright Chad Perrin: Distributed under the terms of the Open Works License