I'm working on creating my own compose key sequences in ~/.XCompose. As I add more and more sequences, occasionally I make typos or use the same sequence for different symbols.


Typo / Non-Existent Codes

<Multi_key> <non-existent-keysym> : other-non-existent-keysym

Full Collision

<Multi_key> <a> <b> : x      # overrule by 2nd rule
<Multi_key> <a> <b> : y

Prefix Collisions

<Multi_key> <a> <b> <c> : y 
<Multi_key> <a> <b> : x      # overruled by 1st rule


Is there a command that validates my ~/.XCompose file. Minimum requirement is a binary answer: Either »your XCompose is error free« or »your XCompose contains errors«. In case there are errors, a helpful error message like »collision for rule sequence prefix « would be welcome.

What I Tried

I created ~/.XCompose containing all errors from above and opened a text editor. The text editor shows no errors (on the console). Correct and non-overruled sequences work, all other sequences are ignored.

I read man 5 XCompose. In the documentation itself I found nothing helpful. I looked at the references at the end of man 5 XCompose. Only mkcomposecache(1) looks promising (judging from the googled manpage), but seems to be missing on my system (Linux Mint 18.3). Neither man -k mkcomposecache nor apt search mkcomposecache find anything.

Edit: As @quixotic suggested, I compiled mkcomposecache from the sources and ran it, but its exits status is 1, no matter what compose file I choose (with or without errors). There is no error message. No cache is generated. Example of how I call the program:

$ mkcomposecache en_US.UTF-8 /usr/share/X11/locale/en_US.UTF-8/Compose /tmp/
* XOpenDisplay: Success
$ echo $?

The file /usr/share/X11/locale/en_US.UTF-8/Compose is Ubuntu's original compose file and should be error free. I guess there is a reason why it is not packaged in the Ubuntu and Arch Linux repositories.

I doubt that mkcomposecache is what I need, even if it would work.


A bit crude, but you could just quickly hack something together using associative arrays, with e.g. awk:

For an input file like

<Multi_key> <a> <t> : y
<Multi_key> <a> <g> : y
<Multi_key> <a> <b> : x
<Multi_key> <a> <b> : y
<Multi_key> <a> <x> <c> : y 
<Multi_key> <a> <x> : x
<Multi_key> <a> <g> : Q
<Multi_key> <a> <n> : y

this command

awk '!d[$2][$3]{d[$2][$3]=1;next} {print $0 " PROBLEM!"}' myFile

will output

<Multi_key> <a> <b> : y PROBLEM!
<Multi_key> <a> <x> : x PROBLEM!
<Multi_key> <a> <g> : Q PROBLEM!

To also see the line it conflicts with:

awk 'c=d[$2][$3]{print $0 " COLLISION: " c;next} {d[$2][$3]=$0}' myFile


<Multi_key> <a> <b> : y COLLISION: <Multi_key> <a> <b> : x
<Multi_key> <a> <x> : x COLLISION: <Multi_key> <a> <x> <c> : y
<Multi_key> <a> <g> : Q COLLISION: <Multi_key> <a> <g> : y
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.