Scala software developer and system engineer for satellite mission planning. Likes Rust and Arch.

Recently I spent a weekend setting up neovim for Rust development, at first basically as a fallback solution to VSCodium and IntelliJ, because these tools became really sluggish on my rather weak laptop, especially in low battery conditions. IntelliJ also likes a good deal of memory, which is a scarce reasource on my laptop, and eats a lot of CPU and thus drains the battery a lot.

But after a while I became really impressed how far neovim got since I last looked at it seriously. Treesitter highlighting, builtin LSP support, Lua really make neovim a modern editor, and enabled a bunch of awesome plugins—I particularly enjoy Telescope, whichkey and lightspeed.

What started as a simple fallback solution quickly became a passion and my primary editor, to a point where I’ve already uninstalled VSCodium.

I don’t think I can drop IntelliJ soon, as it’s just too powerful when it comes to Scala support, but I’ll sure try metals soon.

This is how the result looks like now (left side inside wezterm, right side Neovide):

My neovim (left side inside wezterm, rightside neovide)

As usual, my ever evolving configuration is in my dotfiles repo.

Incidentally, I also dropped Gnome Terminal for good and finally embraced Wezterm which is a really great terminal emulator. I’m a bit surprised that alacritty is so much more popular apparently even though it’s got so much less features (no images, no real hyperlinks, no splits, no tabs, no ligatures 🙈); I can really recommend wezterm for all serious terminal needs.

#archlinux #systemd #tpm2 #secureboot #dracut #luks #sbctl

This article describes my Arch Linux setup which combines Secure Boot with custom keys, TPM2-based full disk encryption and systemd-homed into a fully encrypted and authenticated, yet convenient Linux system.

This setup draws inspiration from Authenticated Boot and Disk Encryption on Linux and Unlocking LUKS2 volumes with TPM2, FIDO2, PKCS#11 Security Hardware on systemd 248 by Lennart Poettering, and combines my previous posts Unlock LUKS rootfs with TPM2 key, Secure boot on Arch Linux with sbctl and dracut, and Arch Linux with LUKS and (almost) no configuration.


#archlinux #systemd #tpm2 #secureboot #dracut #luks #sbctl

Historically cryptsetup and LUKS only supported good old passwords; however recent systemd versions extend cryptsetup with additional key types such as FIDO tokens and TPM devices.

I like the idea of encrypting the rootfs with a TPM2 key; it allows booting without ugly LUKS password prompts but still it keeps data encrypted at rest, and when combined with secure boot also still protects the running system against unauthorized access.

Secure boot will prevent others from placing custom kernels on the unencrypted EFI system partition and booting these, or changing the kernel cmdline, in order to obtain root access to the unlocked rootfs. LUKS encryption with a TPM-based key bound to secure boot state protects the data if someone removes the hard disk and attempts to access it offline, or tries to disable secure boot in order to boot a custom kernel.

I’ve covered secure boot setup in a past article; this article talks about the TPM2-based encryption.


I just learned a nice trick: On Linux I can actually define custom sequences for the Compose key.

I just need to create a ~/.XCompose file and can start to define new sequences for e.g. emojis:

include "%S/en_US.UTF-8/Compose"

<Multi_key> <period> <p> <r> <a> <y> : "🙏"
<Multi_key> <period> <less> <3> <parenright> : "😍"
<Multi_key> <period> <less> <3> <period> : "❤️"
<Multi_key> <period> <less> <3> <asterisk> : "😘"

man 5 Compose documents the format, though Gtk doesn’t seem to support all of it: It doesn’t handle includes apparently, and always seems to include its own hard-coded list of compose sequences.

I found a nice Gist with some sequences, and I started to write my own.


How not to serialize binary data:

import io.circe._

final case class Message(body: ByteString)

object Message {
  implicit val encodeMessage: Encoder[Message] =
    Encoder.instance { message =>
      val array = message.body.toByteArray

Sadly, I actually saw this today… I didn’t do a git blame; I guess I’d never be able to look at that person again 😢


TIL that you can declare a (case) class in a method body. In other words the following is valid Scala code:

def foo(s: String): Unit = {
  final case class Foo(i: Int)

Even after six years Scala continues to surprise.

#docker #kubernetes #gitlab

A node hosts a Gitlab runner and a small k3s cluster which runs a few services as regular kubernetes deployments. A CI job pinned to that runner builds Docker images for these services services, updates the image of the corresponding deployments, and starts a few system and acceptance tests. The CI job does not push those images to the in-house registry; to avoid polluting the registry with hundreds of images it just builds locally.

Each test then scales each deployment to zero replicas to effectively stop all services, clears the system’s underlying database, and scales the service deployments back to a small number of replicas sufficient for testing.

The whole thing runs fine until one day the replicas randomly fail to start.



Some electron-based flatpaks (e.g. Mattermost, see for some reason ignore Gnome’s HTTP proxy settings. In this case we can set the proxy directly inside the affected flatpak.


#rust #zbus #glib

As of zbus 2 beta 7 this no longer works; zbus now insists on managing the connection entirely on its own and provides a Futures-based async server API.

The rust DBus library zbus lets us get hold of the underlying file descriptor of a bus connection, which we can use to plug a zbus connection into the Glib mainloop:


#archlinux #systemd

LWN recently covered a comprehensive guide about discoverable GPT disk images by Lennart Poettering.


Enter your email to subscribe to updates.