I’ve been doing pet projects since I started programming computers more than 20 years ago 👴🏽️, besides learning a lot from these pet
projects, they give me joy. I’m used to saying that ”Coding pet projects is my video game”.
But pet projects are only worth it if you use them, otherwise it’s an experiment, etc… something that will last for a few weeks
and you move on to another thing of interest to have fun.
I used to write ruby code on QtCreator using a ruby language plugin, the problem is
that I do not enjoy coding in Qt/C++ as I did some years ago, so maintaining this plugin up to date for every QtCreator API change
was a pain. Long story short: Pet project archived and now I was in need for a code editor to write Ruby code.
In 2019 I fell in love with Crystal language ❤️ it had the good things I love from Ruby and the good things I missed from typed
and compiled languages like C++. At the time there weren’t many choices to code in Crystal besides the slow VSCode and the
generic non-free Sublime3.
Some experimental GObject binding generator existed, so it was possible to create GTK applications in Crystal, then
I thought: why not create a code editor in GTK the way I want to!?
Tijolo was born 🧱️
I named it Tijolo, means brick in Portuguese, and started the project
somewhere in 2019.
I wanted Tijolo to be very fast like terminal editors, easy to work with split
views like my terminal at the time
(Tilix) and keyboard focused.
With LSP and GtkSourceView
I just needed to glue everything together with some Crystal code, easy like that.
However when I got around the version 0.7.0 I realized a list of problems with the project:
Current GTK bindings had memory leaks, problems with Crystal GC and only supported GTK3.
GTKSourceView API would make some of my ideas for the future harder to implement, besides the problem opening big files.
So I decided to rewrite Tijolo, the new Tijolo would:
Be written in Crystal, the language that most bring me joy to code nowadays.
Use GTK4 and don’t leak memory, so another pet project was born, GI-Crystal, a GObject
binding generator.
Write my own code editor widget instead of using GtkSourceView.
Syntax highlighting would be backed by tree-sitter, so crystal-tree-sitter
was born.
So far this plan is on track, however far away from an end.
I created a GObject binding generator.
I created nice GTK4 bindings using that generator.
I created tree-sitter bindings.
Tijolo GTK3 was simplified and ported to GTK4.
I started to work on a primitive editor widget.
I started to write a PieceTable shard to be used as the buffer of the editor widget.
Then I started to realize the obvious, it was too many things to do for my free time.
Long story short, I decided to learn vim for the third time, but this time with
more seriousness. I started the migration to neovim in December 2025 where
things are more calm at work and it worked, since then I’ve been a happy neovim <3
user.
Conclusion
A few things happened.
From tijolo way of handling editor views,
Batata was born, it’s like a Tilix, I wrote
it because there was no GTK4 version of Tilix.
My GTK4 bindings are being used by some people, it’s good for the ego to
know someone is using your code.
I learned a lot about GTK, GObject and tree-sitter, a knowledge that I doubt
will be useful in my professional life, but is always fun to know.
I wrote RTFM, a GTK application used to read
documentation in the dash format, I use it every day to read Crystal docs.
Update from 2024-03-25
Wireplumber changed and nothing I wrote here works anymore, but one thing still... wireplumber is horrible to configure.
I’m writing this here so I “don’t forget”.
My speakers emit a annoying whitenoise when they are turned on but there’s no signal, the problem is that my ArchLinux setup
is putting the sound board into idle mode to save power after 3 (or 5?) seconds, so every time I stop listeing something,
after 3 (or 5?) seconds the whitenoise starts… really annoying.
I fixed this once, but I was lazy enough to edit system files instead of user files, so today I updated wireplumber again
and the whitenoise was back there.
To let you and future me repeat the same mistake of present mine, if this happen to you, edit these files:
Comment this line from /usr/share/wireplumber/main.lua.d/90-enable-all.lua:
-- Automatically suspends idle nodes after 3 seconds--load_script("suspend-node.lua")
Restart wireplumber:
systemctl --user restart wireplumber
Months ago I had also to edit /usr/share/wireplumber/main.lua.d/50-alsa-config.lua
Uncomment this line at end and set the value to 0 as the comment says.
For personal historical reasons I’m used to US keyboards, so to write portuguese text with those keyboards I need to use the English (US, int. with dead keys) layout that provides compose sequences to write characters like áàãéíóóõúüç.
To generate a ' character I type ' + . It’s this way since ever…. but lately (starting from GTK3 version 3.24.28) somebody decided that this was a bug, not a feature. If someone type this compose sequence the generated character should be ´, not ', and to generate ' you would need to type AltGr + '. The problem is that in protuguese the character ´ alone have no meaning/usage, on the other hand the character ' is used a lot when programming, i.e. this had a huge impact on me.
Long story short, to let GTK behave like I’used to, create a file named .XCompose in your home directory with this:
If you are not used to the XCompose format, check /usr/share/X11/locale/en_US.UTF-8/Compose and you are going to have a idea (or man 5 Compose).
In the past the behavior change that made a headache was ' + c generating ć instead of ç as I was used to, the new compose sequence (that now I’m used to) is AltGr + ,. Hope it helps whoever is reading.
For the ones that don’t know, Crystal was a 2018 hype (however the project exists since 2012) that I only found in 2019, basically it is a language very similar to Ruby in syntax, but that compiles to machine code and is statically type checked.
I was about to start a pet project using Raspberry Pi and Ruby when I noticed the existence of Crystal, so I used the occasion to learn Crystal, just one problem: There’s no crystal in archlinux for raspberry, or at least my efforts to find one weren’t enough.
Not a problem, let’s compile the Crystal compiler into raspberry! This would be amazing, but Crystal compiler is written in Crystal itself, so we have the egg-chicken problem here, the answer? cross compiling!
Cross compiling
By my experience with C and C++, cross compile is a hell, but since Crystal is built on top of LLVM, I gave a try hopping for the best… and was very easy! :-)
My tests were using ArchLinux into a rPi, but this is so simple that must work on every distro.
First do a hello world in Crystal, save it as hello.cr:
puts"Hello Crystal ARM world!"
Install crystal on your computer, sudo pacman -S crystal, then cross compile your hello-world program.
To know why the string “armv6l-unknown-linux-gnueabihf”, go to the rPi, install the llvm-package and type llvm-config --host-target, this is how LLVM describe the platform it is compiling for.
This will compile the file, generate a object file and print lines of code that you need to run in the host machine (the rPi) to link your program, i.e. a GCC command line.
So…. copy the hello.o file to the rPi, then we are going to try to link it. But not so fast, Crystal programs have some dependencies, all but one are solved by installing packages, so in your rPi install the following packages:
$ pacman libevent gc
The missing dependency is libcrystal.a, a tiny one-file plain C static library that we are going to build from Crystal sources.
Building libcrystal.a
As I said, this library is just a single plain C file, so we just need to compile it and generate the static library in the rPi.
$ wget https://raw.githubusercontent.com/crystal-lang/crystal/master/src/ext/sigfault.c
$ cc -c-o sigfault.o sigfault.c
$ ar -rcs libcrystal.a sigfault.o
Then you can put libcrystal.a in /usr/lib/crystal/ext/ or in the same directory of the hello world. The crystal/ext directory is better, since the link commands the Crystal compiler tell us use this, so we need to change nothing.
Finally linking!
Now with everything ready, just link your object file with the commands supplied by the crystal cross compilation.
$ cc 'hello.o'-o'hello'-rdynamic-lpcre-lgc-lpthread /usr/lib/crystal/ext/libcrystal.a \-levent-lrt-ldl-L/usr/lib -L/usr/local/lib
If you think this is too much job… or you are too young in the cross compilation world or I’m too old to remember how painful was to cross compile anything to ARM.
If you have a Windows 32bits and want to try RubyCreator I present you the first RubyCreator binary distribution!
Only Windows 32bits is available since I only have a Windows7 32bits VM available. Consider the Windows distribution beta, I don’t test/use it everyday like I do with the Linux version.
This hand in the screenshot is from my Linux desktop and I’m too lazy to go there take another shot, since I compiled and tested using a VM.
I turned off font anti aliasing, with it on I was not able to proper see the bold text used in RubyCreator sintaxhighlighter, I also didn’t test the Rubocop integration, but it should work, to try it: Add ruby to the system path and make the rubocop gem available for it.
To install it go to Github releases page, download the zip file, unzip and copy the Ruby.dll file to the QtCreator plugins directory. Restart QtCreator and done.
The binary distribution is GPG signed (.sig file) if some nerd want to check if was really me that created it, BTW I need create a new GPG key, mine is too old.
Want a 64bits version?
So help me, I wrote instructions about how to compile the plugin on Windows, it’s not that hard but takes some time.
Conclusions
After too many years without code a single hello world on Windows I have the feeling that Courrier New font is very ugly, but ok, it works.