Linux

Cedilla in Fedora 2025

Years ago I posted about getting the c-cedilla (ç) working in Fedora when using the US International keyboard with deadkeys. This has been a struggle for decades now and every time I set up a new Linux installation, I need to look it up.

That wouldn’t be such a problem, weren’t for the fact that the way to accomplish this seemingly simple task keeps changing over the years, so most of the information you find online is awfully out of date.

So for 2025, based on my experience with Fedora 42 (the current version at time of writing) – I suspect it would work similarly with other distros, but I cannot confirm it – this is how I did it.

First add these two lines to /etc/environment –

export GTK_IM_MODULE=cedilla
export QT_IM_MODULE=cedilla

And then in your home dir, add a file named .XCompose with this –

<dead_acute> <C>			: "Ç"	U0106 # LATIN CAPITAL LETTER C WITH CEDILLA
<dead_acute> <c>			: "ç"	U0107 # LATIN SMALL LETTER C WITH CEDILLA

Then reboot and it should just work. To be fair, this is the easiest it’s been for years to get this done.

As a bonus, there are a few other changes that I’ve made in my .XCompose file to solve some annoyances I have with the US-intl keyboard in Linux. When I type fast, I tend to accidentally end up with a lot of mistakenly accented consonants that I don’t need in any of the languages I write in.

These are, of course, entirely up to you if you want them and have nothing to do with the cedilla. You can find them on Github.

Hopefully the search engine gods will help someone out there find this when they need it. Might just be me in the not-too-distant future.

Cedilha no Fedora 25

Quem utiliza teclado US Internacional para escrever no Linux já deve ter dado de cara com o fato de que na maioria das distribuições, a combinação ‘+c gera um “ć” em vez de um “ç”. Resolver isso no Fedora 25 é fácil, mas não evidente.

tl;dr – eu criei este script que faz todos os passos abaixo automaticamente. Basta rodar isso:

curl https://raw.githubusercontent.com/robteix/c-cedilla-fedora/master/c-cedilla-fedora | bash

Se você preferir não executar o script, continue lendo.

Primeiro, vamos criar um novo mapa de teclado para seu usuário. Rode o comando abaixo:

sed -e 's,\xc4\x86,\xc3\x87,g' \
    -e 's,\xc4\x87,\xc3\xa7,g' \
    < /usr/share/X11/locale/en_US.UTF-8/Compose > ~/.XCompose

Isso copia o arquivo de mapeamento de teclas do Fedora para o diretório $HOME do usuário, substituindo o “Ć” por um “Ç”.

Agora vamos configurar o GNOME para que ele não controle a configuração do teclado, para que possamos usar nossa própria:

gsettings set org.gnome.settings-daemon.plugins.keyboard active false

Para selecionar o input method apropriado, o Fedora fornece um programinha chamado im-chooser que não é instalado por padrão. Para instalá-lo:

sudo dnf install im-chooser

Por fim, executamos o im-chooser e escolhemos “Use X Compose table”:

Clique em “Log out” para aplicar as modificações e a partir de agora deve ser possível gerar o c-cedilha com a combinação ‘+c.

Linux Kernel Linked List Explained

I appreciate beautiful, readable code. And if someone were to ask me for an example of beautiful code, I’ve always had the answer ready: the linked list implementation in the Linux kernel.

The code is gorgeous in its simplicity, clarity, and amazing flexibility. If there’s ever a museum for code, this belongs there. It is a masterpiece of the craft.

I was just telling a friend about it while we talked about beautiful code and he found this piece that I share here: Linux Kernel Linked List Explained.

Counting Bits Like the Kernel

Kernel code contains algorithms that look unnecessarily peculiar until the constraints are visible. Population count, the number of set bits in a machine word, is a good example.

The obvious C version examines every bit:

unsigned int count_bits(unsigned long word)
{
        unsigned int n = 0;

        while (word) {
                n += word & 1;
                word >>= 1;
        }
        return n;
}

This performs one iteration for every bit position up to the highest set bit. A sparse bitmap still pays for all the zeros in between.

Brian Kernighan’s familiar operation removes the lowest set bit at each iteration:

unsigned int count_bits(unsigned long word)
{
        unsigned int n = 0;

        while (word) {
                word &= word - 1;
                n++;
        }
        return n;
}

Subtracting one flips the lowest set bit to zero and turns lower zeros into ones. The & keeps everything above that bit and clears the changed suffix. The loop therefore runs once per set bit.

That is excellent for sparse words and less impressive for dense ones. Kernels also use table lookups and architecture-specific instructions where available. A byte table has predictable work but adds memory access; a processor instruction can win decisively but needs dispatch or compile-time selection. There is no universally fastest source fragment independent of data and machine.

Word width matters too. Kernel types and helpers make that choice explicit, while a casual userspace benchmark can accidentally compare different widths and announce a victory produced by less work.

I benchmarked the two loops over generated sparse and dense arrays, keeping generation outside the timed section. As expected, the clear-lowest-bit version dominated sparse input. Dense input narrowed the gap considerably. Repeating one constant word produced lovely numbers and measured the compiler more than the routine, so I stopped doing that.

The broader lesson from kernel work is to understand the representation before admiring the trick. Bitmaps pack state compactly and permit word-at-a-time operations, but contention, cache placement, and scan direction can matter more than shaving an instruction from population count.

I like this algorithm because its mechanism fits in one sentence and its performance caveat requires another. Most optimization stories should have both sentences. The ones with only the first usually end in a benchmark that accidentally proves the author’s laptop exists.