<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>cashmere</title>
    <subtitle>everything about nixos, rust and GLORIOUS SSH</subtitle>
    <link rel="self" type="application/atom+xml" href="/atom.xml"/>
    <link rel="alternate" type="text/html" href="/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-07-18T00:00:00+00:00</updated>
    <id>/atom.xml</id>
    <entry xml:lang="en">
        <title>The Fediverse Is Trash and Garbage</title>
        <published>2026-07-18T00:00:00+00:00</published>
        <updated>2026-07-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/the-fediverse-is-trash-and-garbage/"/>
        <id>/blog/the-fediverse-is-trash-and-garbage/</id>
        
        <content type="html" xml:base="/blog/the-fediverse-is-trash-and-garbage/">&lt;h1 id=&quot;re-the-fediverse-was-right&quot;&gt;RE: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.lvmbdv.dev&#x2F;posts&#x2F;the-fediverse-was-right&#x2F;&quot;&gt;the fediverse was right&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;If you want a detailed breakdown of the many flaws of the fediverse, please watch &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=QSZSGeecalc&amp;amp;t=27s&amp;amp;pp=ygUQZGVuc2hpIGZlZGl2ZXJzZQ%3D%3D&quot;&gt;Denshis&lt;&#x2F;a&gt;&#x27;s video.&lt;&#x2F;p&gt;
&lt;p&gt;I will add my own take on why the fediverse is straight-up dogshit.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;try-to-interact-with-the-fediverse-as-a-single-entity&quot;&gt;Try to interact with the fediverse as a single entity&lt;&#x2F;h1&gt;
&lt;p&gt;Let&#x27;s assume you want to have your independent website, want to share your posts and&#x2F;or thoughts with others on the fediverse, but without self-hosting a fediverse instance. How hard can it be?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-clusterfuck-begins&quot;&gt;The clusterfuck begins&lt;&#x2F;h2&gt;
&lt;p&gt;Here are some, but not limited to, specifications on how to reach people:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.w3.org&#x2F;TR&#x2F;activitystreams-core&#x2F;&quot;&gt;ActivityStreams 2.0 Core&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.w3.org&#x2F;TR&#x2F;activitypub&#x2F;&quot;&gt;ActivityPub&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;datatracker.ietf.org&#x2F;doc&#x2F;html&#x2F;rfc7033&quot;&gt;WebFinger (RFC 7033)&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;em&gt;Don&#x27;t ask me what a WebFinger is; I don&#x27;t fucking know.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Why do I assume that it&#x27;s harder to set up than &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;discourse.nixos.org&#x2F;t&#x2F;why-isnt-my-navidrome-service-seeing-my-music-dir&#x2F;46836&quot;&gt;mounting your music folder to Navidrome on NixOS&lt;&#x2F;a&gt;? Because I already went through the hell!&lt;&#x2F;p&gt;
&lt;p&gt;At the same time, we already have a well-established way to share blog posts and news, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;RSS&quot;&gt;SINCE March 15, 1999&lt;&#x2F;a&gt;. Believe it or not, many news sites offer an RSS feed. While it&#x27;s not as common as it used to be, it&#x27;s much easier to interact with, read, and extend an RSS feed than to interact with the fediverse. If your favorite site doesn&#x27;t offer an RSS feed, you can brute-force one with e.g. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;rss-bridge.org&#x2F;&quot;&gt;RSS-Bridge&lt;&#x2F;a&gt;. Now what should you do if you cannot find a way? Then ask your favorite clanker; they will find one ;).&lt;&#x2F;p&gt;
&lt;h1 id=&quot;which-already-working-protocol-shall-we-enshittify-next&quot;&gt;Which already working protocol shall we enshittify next?&lt;&#x2F;h1&gt;
&lt;blockquote&gt;
&lt;p&gt;○ What&#x27;s missing&lt;&#x2F;p&gt;
&lt;p&gt;Git forges. That&#x27;s the obvious one.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Hell no, please not my beloved &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;charmbracelet&#x2F;soft-serve&quot;&gt;git instance&lt;&#x2F;a&gt; which anyone can reach over &lt;code&gt;ssh git@git.cashmere.rs&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;don-t-i-participate-myself-on-bluesky-and-even-link-it&quot;&gt;Don&#x27;t I participate myself on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;bsky.app&#x2F;profile&#x2F;cashmere.rs&quot;&gt;bluesky&lt;&#x2F;a&gt; and even &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cashmere.rs&#x2F;feed&#x2F;&quot;&gt;link&lt;&#x2F;a&gt; it?&lt;&#x2F;h1&gt;
&lt;p&gt;That&#x27;s 100% true! Bluesky is backed by VC money. That&#x27;s also the reason why almost all of my posts there are trash posts :). If you want the good esoteric stuff, you have to add my &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cashmere.rs&#x2F;atom.xml&quot;&gt;RSS feed&lt;&#x2F;a&gt; to your reader or visit my website. Even AI scrapers visit my site and extract value from my website. Why don&#x27;t you do the same???&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;With that being said, Happy Hacking!&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>My friends ditched the snowflake for the shepherd. I went with the devil instead</title>
        <published>2026-07-11T00:00:00+00:00</published>
        <updated>2026-07-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/my-friends-ditched-the-snowflake-for-the-shepherd-i-went-with-the-devil-instead/"/>
        <id>/blog/my-friends-ditched-the-snowflake-for-the-shepherd-i-went-with-the-devil-instead/</id>
        
        <content type="html" xml:base="/blog/my-friends-ditched-the-snowflake-for-the-shepherd-i-went-with-the-devil-instead/">&lt;h1 id=&quot;wtf&quot;&gt;WTF???&lt;&#x2F;h1&gt;
&lt;p&gt;Let me explain…&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Yes, it&#x27;s going to get really esoteric.&lt;&#x2F;li&gt;
&lt;li&gt;Nix is going to play a role, but not in the way I usually used to.&lt;&#x2F;li&gt;
&lt;li&gt;I never thought this day would ever come, but here we are.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;what-happened&quot;&gt;What happened?&lt;&#x2F;h1&gt;
&lt;p&gt;My friends and I wanted to try out something new. &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;joshblais.com&#x2F;blog&#x2F;installing-non-guix&#x2F;&quot;&gt;Josh&lt;&#x2F;a&gt; switched from NixOS to Guix, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;linuxmaxxing.com&#x2F;posts&#x2F;09_guix&#x2F;&quot;&gt;Linuxmaxxing swirled out to the Shepherd&lt;&#x2F;a&gt; and I knew my time had come too.&lt;&#x2F;p&gt;
&lt;p&gt;I decided to try out &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;freebsd.org&quot;&gt;FreeBSD&lt;&#x2F;a&gt;. I&#x27;m going to run NixOS as my main operating system for now so I don&#x27;t break my running system, while still experiencing the magic of FreeBSD thanks to the power of QEMU and a type 1 hypervisor.&lt;&#x2F;p&gt;
&lt;p&gt;I can&#x27;t recommend virtualization enough. Why and how should be somewhat clear to anyone who is even reading this post. &lt;em&gt;(Probably 2 people)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;how-did-it-come-to-this&quot;&gt;How did it come to this?&lt;&#x2F;h1&gt;
&lt;p&gt;After nearly 3 years of daily driving NixOS, the spark is gone. I don&#x27;t just need some distance, I want to feel that curiosity I had at the beginning again.&lt;&#x2F;p&gt;
&lt;p&gt;There was virtually no &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cashmere.rs&#x2F;emacs-window-manager&#x2F;&quot;&gt;device&lt;&#x2F;a&gt; or server where I didn&#x27;t slap Nix&#x2F;NixOS on. Some went super fast, others cost me weeks.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s keep it short, most of what I wanted to test and implement, I managed to do.&lt;&#x2F;p&gt;
&lt;p&gt;Call me crazy and obsessed, but yes, the following points also made me question my stance towards the current Nix ecosystem.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;flake-parts&quot;&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;flake.parts&#x2F;&quot;&gt;flake.parts&lt;&#x2F;a&gt;&lt;&#x2F;h1&gt;
&lt;p&gt;Once again, to preface: flake.parts is in itself a very strong project that takes Nix to an &lt;strong&gt;endgame&lt;&#x2F;strong&gt;. I just wonder if &lt;em&gt;I&lt;&#x2F;em&gt; need this endgame. For example, I &quot;maintain&quot; my own &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git.cashmere.rs&#x2F;pkgs.git&quot;&gt;packages&lt;&#x2F;a&gt;. There I use flake.parts and I think it&#x27;s really a project where I see and benefit from the abstractions. However, I think it all became too much when the following &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=-TRbzkw6Hjs&quot;&gt;video&lt;&#x2F;a&gt; by vimjoyer was released.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;vimjoyer-dendritic-pattern-and-abstraction-slop&quot;&gt;Vimjoyer, dendritic pattern and abstraction slop&lt;&#x2F;h1&gt;
&lt;p&gt;I started with a simple configuration.nix, then at some point upgraded to a standard flake.nix, with which I was more than satisfied, but the dendritic pattern had really reached a peak of abstraction where I myself no longer had any overview of what was in my main flake.nix where I not only manage like 5 devices at the same time, but suddenly also had custom packages and services that were self-contained somewhere, yet still brought a dependency with them.&lt;&#x2F;p&gt;
&lt;p&gt;I was so overwhelmed that I switched straight to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;jade.fyi&#x2F;blog&#x2F;pinning-nixos-with-npins&#x2F;&quot;&gt;npins&lt;&#x2F;a&gt; to somehow get an overview again.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;surprise-we-were-all-overwhelmed&quot;&gt;Surprise, we were all overwhelmed&lt;&#x2F;h2&gt;
&lt;p&gt;I thought I was the only one feeling this way, but luckily I wasn&#x27;t. And to close the circle, I think some like-minded people from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;webring.cashmere.rs&#x2F;&quot;&gt;#technicalrenaissance&lt;&#x2F;a&gt; are looking around further. &lt;em&gt;(as in the case of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;guix.gnu.org&#x2F;&quot;&gt;guix&lt;&#x2F;a&gt;)&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;unpopular-nix-opinions&quot;&gt;Unpopular Nix Opinions&lt;&#x2F;h2&gt;
&lt;p&gt;And to find some closure, here are some unpopular NixOS opinions, just to piss people off: &lt;em&gt;(these opinions would have pissed me off too until a few months ago, lmao.)&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;the use of third party flakes is the same as the AUR.&lt;&#x2F;li&gt;
&lt;li&gt;You are not unique, just because you even vibecoded your system configuration.&lt;&#x2F;li&gt;
&lt;li&gt;NixOS is currently overhyped af.&lt;&#x2F;li&gt;
&lt;li&gt;Your reproducible configuration won&#x27;t help you if you can&#x27;t even restore the state of your services lol.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;let-s-face-the-devil&quot;&gt;Let&#x27;s face the devil&lt;&#x2F;h1&gt;
&lt;p&gt;From the day I realized how powerful &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cashmere.rs&#x2F;wiki&#x2F;zfs&#x2F;&quot;&gt;ZFS&lt;&#x2F;a&gt; is, I came to the conclusion to try out FreeBSD.&lt;&#x2F;p&gt;
&lt;p&gt;Here are my takes on why I currently enjoy FreeBSD&lt;&#x2F;p&gt;
&lt;h2 id=&quot;it-feels-more-familiar-than-i-expected&quot;&gt;It feels more familiar than I expected&lt;&#x2F;h2&gt;
&lt;p&gt;If you are somewhat familiar with the CLI, FreeBSD will feel just like home.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;still-different-from-linux&quot;&gt;Still different from Linux&lt;&#x2F;h2&gt;
&lt;p&gt;FreeBSD is still unique in its own ways. There are many exciting concepts baked into the native OS such as Jails, ZFS, Ports etc.&lt;&#x2F;p&gt;
&lt;p&gt;I guess you have to try it out yourself to get it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;insanely-good-docs&quot;&gt;Insanely good docs&lt;&#x2F;h2&gt;
&lt;p&gt;If you&#x27;ve heard anything about BSD, it&#x27;s their insanely good documentation. I can attest to that.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ports&quot;&gt;Ports&lt;&#x2F;h2&gt;
&lt;p&gt;FreeBSD&#x27;s own approach to Nix overrides or Gentoo USE flags.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;another-perspective-on-how-you-could-manage-your-systems&quot;&gt;Another perspective on how you could manage your systems&lt;&#x2F;h2&gt;
&lt;p&gt;Coming from NixOS, it&#x27;s different how FreeBSD manages its systems. It feels unfamiliar (in a very positive way), as I used to think that NixOS and especially declarative configurations are the de facto end goal.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;should-you-try&quot;&gt;Should you try…&lt;&#x2F;h1&gt;
&lt;p&gt;Just try it out, as I did. Don&#x27;t ask anybody…&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>kitty-graphics.el v1.0.0: Document Zoom and Pan, a Doctor Command, and a Stable 1.0</title>
        <published>2026-06-16T00:00:00+00:00</published>
        <updated>2026-06-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/kitty-graphicsel-v100-document-zoom-pan-and-doctor/"/>
        <id>/blog/kitty-graphicsel-v100-document-zoom-pan-and-doctor/</id>
        
        <content type="html" xml:base="/blog/kitty-graphicsel-v100-document-zoom-pan-and-doctor/">&lt;p&gt;&lt;code&gt;kitty-graphics.el&lt;&#x2F;code&gt; is 1.0.0. The package has been my daily driver for months now, across Kitty, foot, WezTerm, Ghostty, and tmux, and it has reached the point where I trust it for real work instead of treating it as an experiment. This release is the stable cut: a large amount of rendering, performance, and reliability work landed since v0.6.0, and 1.0.0 is where it all settles.&lt;&#x2F;p&gt;
&lt;p&gt;If you are new here: it renders images, video, scaled headings, and documents directly in terminal Emacs (&lt;code&gt;emacs -nw&lt;&#x2F;code&gt;), picking the Kitty graphics protocol or Sixel automatically depending on your terminal.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;a-stable-1-0&quot;&gt;A stable 1.0&lt;&#x2F;h1&gt;
&lt;p&gt;v0.6.0 added inline video, a Chromium browser, and Kitty graphics through tmux. Everything since then has been about making the package solid: a redisplay engine that does nothing when nothing changed, conversions that no longer block Emacs, daemon support for several terminals at once, and a long bug-sweep over the process, overlay, and protocol lifecycles. 1.0.0 bundles all of it, plus the new document viewer below.&lt;&#x2F;p&gt;
&lt;p&gt;Nothing in your config needs to change to upgrade. The entry point is still &lt;code&gt;kitty-graphics-setup&lt;&#x2F;code&gt;, which works the same for a plain terminal Emacs and for a daemon with several &lt;code&gt;emacsclient -t&lt;&#x2F;code&gt; clients attached.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;document-zoom-and-pan&quot;&gt;Document zoom and pan&lt;&#x2F;h1&gt;
&lt;p&gt;The doc-view integration was reworked into something I actually want to read PDFs in. Pages now render centered in the window, &lt;code&gt;n&lt;&#x2F;code&gt; and &lt;code&gt;p&lt;&#x2F;code&gt; flip pages, and &lt;code&gt;+&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;-&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;0&lt;&#x2F;code&gt; zoom.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;posts&#x2F;kitty-graphicsel-v100-document-zoom-pan-and-doctor&#x2F;doc-view.gif&quot; alt=&quot;img&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;On the Kitty backend a zoomed page is clipped to the window and panned by scrolling, the way pdf-tools behaves, so you can zoom into a figure and move around it instead of overflowing the buffer. On Sixel the page renders at fit size. PDF, DVI, PostScript, and EPUB all go through the same path.&lt;&#x2F;p&gt;
&lt;p&gt;It is also converter-agnostic now: if MuPDF&#x27;s &lt;code&gt;mutool&lt;&#x2F;code&gt; is on &lt;code&gt;PATH&lt;&#x2F;code&gt;, doc-view uses it automatically, and Ghostscript still works as before. MuPDF is noticeably faster and sharper for PDFs.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;faster-lighter-rendering&quot;&gt;Faster, lighter rendering&lt;&#x2F;h1&gt;
&lt;p&gt;The biggest invisible change is that refreshes are skipped entirely when nothing on screen changed. Each visible image window stores a cheap signature (buffer, modification tick, displayed region, hscroll, pixel size) after a successful refresh, and the post-command scheduler does nothing while every signature still matches. &lt;code&gt;kitty-gfx-skip-clean-refresh&lt;&#x2F;code&gt; (default &lt;code&gt;t&lt;&#x2F;code&gt;) is the escape hatch.&lt;&#x2F;p&gt;
&lt;p&gt;Non-PNG images (jpeg, webp, svg, and so on) are now converted to PNG in a background process instead of blocking Emacs, controlled by &lt;code&gt;kitty-gfx-async-conversion&lt;&#x2F;code&gt; (default &lt;code&gt;t&lt;&#x2F;code&gt;). The overlay reserves its space immediately and the image appears once the conversion lands. Results are cached per file mtime, and base64 payloads are cached in memory (bounded by &lt;code&gt;kitty-gfx-base64-cache-bytes&lt;&#x2F;code&gt;, 64 MiB, LRU), so sending the same image to a second terminal skips both the read and the encode.&lt;&#x2F;p&gt;
&lt;p&gt;Transmitting an image to a terminal that does not hold its data yet no longer happens synchronously inside the refresh loop. Transmits go through a queue drained one image per timer tick, so keystrokes stay responsive while a freshly attached client catches up.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;daemon-and-multiple-terminals&quot;&gt;Daemon and multiple terminals&lt;&#x2F;h1&gt;
&lt;p&gt;Graphics now work under &lt;code&gt;emacs --daemon&lt;&#x2F;code&gt; with several &lt;code&gt;emacsclient -t&lt;&#x2F;code&gt; clients at the same time. Placements, transmissions, and cleanup are routed per client terminal: each one keeps its own backend detection, cell size, text-sizing level, and transmitted-image set, so a client in Kitty and another in a Sixel terminal both render correctly and concurrently. Inline video and the casty browser stay bound to the terminal they were launched on, since each streams a single byte stream to one tty.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;sixel-tuning&quot;&gt;Sixel tuning&lt;&#x2F;h1&gt;
&lt;p&gt;Sixel encoding gained real knobs. &lt;code&gt;kitty-gfx-sixel-dither&lt;&#x2F;code&gt; (nil, &lt;code&gt;&quot;none&quot;&lt;&#x2F;code&gt;, &lt;code&gt;&quot;fs&quot;&lt;&#x2F;code&gt;, or &lt;code&gt;&quot;atkinson&quot;&lt;&#x2F;code&gt;) and &lt;code&gt;kitty-gfx-sixel-colors&lt;&#x2F;code&gt; (palette size, default 256) map onto img2sixel&#x27;s &lt;code&gt;-d&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;-p&lt;&#x2F;code&gt; and ImageMagick&#x27;s &lt;code&gt;-dither&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;-colors&lt;&#x2F;code&gt;. ImageMagick now resizes before quantizing so the palette reduction actually sticks. Dropping to 16 colors with dithering off cut the test-image payload from 2042 to 1412 bytes with img2sixel and from 4904 to 1712 with magick, which matters a lot in tmux where every refresh re-emits the whole DCS payload.&lt;&#x2F;p&gt;
&lt;p&gt;When img2sixel encodes a source larger than the target box and ImageMagick is present, the image is pre-scaled to a temp PNG first so quantization runs on the small image. tmux detection is also per terminal now: each client&#x27;s own tmux server is queried for its version and &lt;code&gt;allow-passthrough&lt;&#x2F;code&gt; state, so daemon clients in different tmux servers detect independently.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;headings-that-stay-put&quot;&gt;Headings that stay put&lt;&#x2F;h1&gt;
&lt;p&gt;OSC 66 scaled headings were reworked to feel native. Editing a scaled heading no longer makes it vanish and reappear: the overlay stays in place, the text shows at normal size while you type, and a debounced rescan re-renders it where it is. Heading widths use &lt;code&gt;string-width&lt;&#x2F;code&gt;, so CJK and emoji headings get their full footprint, and scaled headings no longer overwrite inline images. Instrumentation is lazy by default (&lt;code&gt;kitty-gfx-heading-scan-visible-only&lt;&#x2F;code&gt;), scanning only the visible region plus a margin, which keeps activation instant in files with thousands of headings.&lt;&#x2F;p&gt;
&lt;p&gt;Heading rendering is best for reading and navigating. Editing works far better than before, but only one window per buffer renders the scaled text, so it is still primarily a viewing feature.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;reliability-and-diagnostics&quot;&gt;Reliability and diagnostics&lt;&#x2F;h1&gt;
&lt;p&gt;New &lt;code&gt;M-x kitty-gfx-doctor&lt;&#x2F;code&gt; prints a diagnostic report: the active backend, the queried cell size and text-sizing level, tmux state, the resolved Sixel encoder, and which of the external programs the package relies on are actually installed. When a terminal is not supported it now tells you why instead of just refusing, and a missing ImageMagick says so instead of letting images silently never appear.&lt;&#x2F;p&gt;
&lt;p&gt;Every blocking external command (ImageMagick, identify, ffmpeg, typst) now runs under a watchdog bounded by &lt;code&gt;kitty-gfx-process-timeout&lt;&#x2F;code&gt; (15s), so a corrupt or pathological file can no longer freeze Emacs. A failed or timed-out Sixel encode shows a visible marker and a one-time message naming the encoder, rather than blank cells retried on every refresh.&lt;&#x2F;p&gt;
&lt;p&gt;Two compatibility fixes worth calling out: the cell-size and text-sizing startup probes no longer eat keystrokes typed while they wait, and the probes are now deferred off the mode-enable path so they stop consuming &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;benjaminor&#x2F;kkp&quot;&gt;kkp.el&lt;&#x2F;a&gt;&#x27;s keyboard-protocol reply, which could break it depending on hook order. Beyond that, 1.0.0 includes a full bug-sweep over the process, overlay, and protocol lifecycles, verified finding by finding.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;installation&quot;&gt;Installation&lt;&#x2F;h1&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;use-package&lt;&#x2F;span&gt;&lt;span&gt; kitty-graphics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;straight&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;host github &lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;repo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt; &amp;quot;cashmeredev&#x2F;kitty-graphics.el&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;not&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;display-graphic-p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;config&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span&gt;setq kitty-gfx-enable-video t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span&gt;kitty-graphics-setup&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you run into bugs or have feature requests, open an issue on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cashmeredev&#x2F;kitty-graphics.el&#x2F;issues&quot;&gt;GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Release: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cashmeredev&#x2F;kitty-graphics.el&#x2F;releases&#x2F;tag&#x2F;v1.0.0&quot;&gt;v1.0.0 on GitHub&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>kitty-graphics.el v0.6.0: Inline Video, a Web Browser, and Improved tmux Support</title>
        <published>2026-06-06T00:00:00+00:00</published>
        <updated>2026-06-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/kitty-graphicsel-v060-video-browser-and-improved-tmux/"/>
        <id>/blog/kitty-graphicsel-v060-video-browser-and-improved-tmux/</id>
        
        <content type="html" xml:base="/blog/kitty-graphicsel-v060-video-browser-and-improved-tmux/">&lt;p&gt;After months of work since the last release, &lt;code&gt;kitty-graphics.el&lt;&#x2F;code&gt; v0.6.0 is out, and it is a big one. Back in the v0.4.0 notes I said I wanted to push terminal Emacs further, all the way to a full-fledged Chromium browser. That sounded ambitious at the time. With v0.6.0 it is here, alongside inline video playback and Kitty graphics that finally work through tmux.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;inline-video-playback&quot;&gt;Inline video playback&lt;&#x2F;h1&gt;
&lt;p&gt;You can now play actual videos inside terminal Emacs. Not a thumbnail, not a still frame, the real thing with audio, backed by &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;mpv.io&quot;&gt;mpv&lt;&#x2F;a&gt; and the Kitty graphics protocol.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;posts&#x2F;kitty-graphicsel-v060-video-browser-and-improved-tmux&#x2F;mpv-showcase.gif&quot; alt=&quot;img&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;M-x kitty-gfx-play-video&lt;&#x2F;code&gt; opens a video in a dedicated buffer and starts playing. The controls are kept simple:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SPC&lt;&#x2F;code&gt; to pause and resume&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;q&lt;&#x2F;code&gt; to stop and go back to the previous buffer&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;?&lt;&#x2F;code&gt; to show the keymap&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Under the hood mpv runs on a PTY with &lt;code&gt;--vo=kitty&lt;&#x2F;code&gt;, its frame stream is forwarded straight to the terminal, and a small JSON IPC socket drives pause and resume. Only one video plays at a time, and it pauses itself when you scroll it out of view.&lt;&#x2F;p&gt;
&lt;p&gt;dired and dirvish get previews too. Video files show a thumbnail in the preview pane as you move the cursor, and &lt;code&gt;kitty-gfx-dired-play-video&lt;&#x2F;code&gt; (or &lt;code&gt;RET&lt;&#x2F;code&gt; in dirvish) plays them full-frame. The dirvish inline playback is opt-in:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;setq kitty-gfx-dirvish-video-inline-preview t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Big thanks to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;unship&quot;&gt;unship&lt;&#x2F;a&gt;, whose frame-placement work is what made the dirvish video previews possible.&lt;&#x2F;p&gt;
&lt;p&gt;This is Kitty-backend only. The Sixel path re-emits every frame, which is far too expensive for video, so I did not pretend it works there.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;inline-web-browser&quot;&gt;Inline web browser&lt;&#x2F;h1&gt;
&lt;p&gt;This is the one I teased. &lt;code&gt;kitty-gfx-browse&lt;&#x2F;code&gt; opens a real Chromium page inside an Emacs buffer.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;posts&#x2F;kitty-graphicsel-v060-video-browser-and-improved-tmux&#x2F;casty-demo.gif&quot; alt=&quot;img&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It works by embedding &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cashmeredev&#x2F;casty&quot;&gt;casty&lt;&#x2F;a&gt;, a headless-Chrome bridge (my fork of &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sanohiro&#x2F;casty&quot;&gt;sanohiro&#x2F;casty&lt;&#x2F;a&gt;), in a new embed mode. casty renders the page to PNG frames over the Kitty graphics protocol, and Emacs drives it over an IPC socket: scrolling, history, reload, mouse clicks, and Vimium-style link hints. The keybindings are vim-flavoured and mirrored into evil if you use it:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;j&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;k&lt;&#x2F;code&gt; scroll, &lt;code&gt;C-f&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;C-b&lt;&#x2F;code&gt; page&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;H&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;L&lt;&#x2F;code&gt; back and forward, &lt;code&gt;r&lt;&#x2F;code&gt; reload&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;o&lt;&#x2F;code&gt; or &lt;code&gt;:&lt;&#x2F;code&gt; to open a URL&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;f&lt;&#x2F;code&gt; for link hints, then type the label to follow it&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;q&lt;&#x2F;code&gt; to quit&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Enable it with &lt;code&gt;kitty-gfx-enable-browser&lt;&#x2F;code&gt; and point &lt;code&gt;kitty-gfx-casty-program&lt;&#x2F;code&gt; at the casty launcher. casty ships its own headless Chrome, but you can also point it at a browser you already have:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;setq kitty-gfx-casty-chrome &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;&amp;quot;&#x2F;usr&#x2F;bin&#x2F;chromium&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is experimental and, for now, Kitty terminal only. It is not reliable on Ghostty yet, so I will not promise more than that.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;kitty-graphics-in-tmux&quot;&gt;Kitty graphics in tmux&lt;&#x2F;h1&gt;
&lt;p&gt;The other half of tmux support landed. v0.5.0 unlocked Sixel inside tmux; v0.6.0 makes the Kitty graphics protocol itself work there. Kitty&#x27;s APC sequences used to get eaten by tmux, so they are now wrapped in the DCS passthrough envelope when &lt;code&gt;allow-passthrough on&lt;&#x2F;code&gt; is set:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;font-style: italic;&quot;&gt;;; on by default&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;setq kitty-gfx-tmux-passthrough t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There is also a new Unicode-placeholder placement mode (&lt;code&gt;kitty-gfx-kitty-placement-mode&lt;&#x2F;code&gt;, &lt;code&gt;auto&lt;&#x2F;code&gt; by default). Instead of placing images at absolute pixel coordinates, the image lives in the multiplexer&#x27;s character grid as placeholder cells, so pane and window switches are handled by tmux naturally with no ghost images left behind. The detector also recognises Ghostty and WezTerm when they are hidden behind tmux.&lt;&#x2F;p&gt;
&lt;p&gt;One honest caveat: tmux&#x27;s cell buffer is not pixel-aware, so an image can stick to its old spot after scrolling until those cells are overwritten. That is an upstream tmux limitation, not something the package can fix.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;installation&quot;&gt;Installation&lt;&#x2F;h1&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;use-package&lt;&#x2F;span&gt;&lt;span&gt; kitty-graphics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;straight&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;host github &lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;repo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt; &amp;quot;cashmeredev&#x2F;kitty-graphics.el&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;not&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;display-graphic-p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;config&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span&gt;setq kitty-gfx-enable-video t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span&gt;kitty-graphics-mode &lt;&#x2F;span&gt;&lt;span style=&quot;color: #EF9F76;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you run into bugs or have feature requests, open an issue on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cashmeredev&#x2F;kitty-graphics.el&#x2F;issues&quot;&gt;GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Release: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cashmeredev&#x2F;kitty-graphics.el&#x2F;releases&#x2F;tag&#x2F;v0.6.0&quot;&gt;v0.6.0 on GitHub&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>kitty-graphics.el v0.5.0: tmux support, sixel performance, typst support</title>
        <published>2026-04-26T00:00:00+00:00</published>
        <updated>2026-04-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/kitty-graphicsel-v050-tmux-support-sixel-performance-typst-support/"/>
        <id>/blog/kitty-graphicsel-v050-tmux-support-sixel-performance-typst-support/</id>
        
        <content type="html" xml:base="/blog/kitty-graphicsel-v050-tmux-support-sixel-performance-typst-support/">&lt;p&gt;I&#x27;m thrilled to announce &lt;code&gt;kitty-graphics.el v0.5.0&lt;&#x2F;code&gt;!&lt;&#x2F;p&gt;
&lt;h1 id=&quot;tmux-support&quot;&gt;tmux support&lt;&#x2F;h1&gt;
&lt;p&gt;We now officially support tmux with sixel. &lt;img src=&quot;&#x2F;images&#x2F;post&#x2F;new&#x2F;tmux-support.png&quot; alt=&quot;img&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;typst-inline-equations-support&quot;&gt;Typst inline equations support&lt;&#x2F;h1&gt;
&lt;p&gt;We now support Typst inline equations!&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m a big fan of Typst myself.&lt;&#x2F;p&gt;
&lt;p&gt;Thank you &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;spencermaema&quot;&gt;spencermaema&lt;&#x2F;a&gt; for the suggestion! &lt;img src=&quot;&#x2F;images&#x2F;post&#x2F;new&#x2F;typst-preview.png&quot; alt=&quot;img&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;sixel-support-improvements&quot;&gt;Sixel support improvements&lt;&#x2F;h1&gt;
&lt;p&gt;Sixel received a significant performance enhancement thanks to this &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timfel&#x2F;sixel-graphics.el&quot;&gt;fork&lt;&#x2F;a&gt;, which incorporated some excellent ideas that greatly accelerated the image display implementation.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;better-windows-terminal-support&quot;&gt;Better Windows Terminal support&lt;&#x2F;h1&gt;
&lt;p&gt;Thanks to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;timfel&quot;&gt;Timfel&lt;&#x2F;a&gt;&#x27;s tests and commits, the detection of the Windows Terminal was improved.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>kitty-graphics.el v0.4.0: Sixel, Text Sizing, and agent-shell</title>
        <published>2026-04-07T00:00:00+00:00</published>
        <updated>2026-04-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/kitty-graphicsel-v040-sixel-text-sizing-and-agent-shell/"/>
        <id>/blog/kitty-graphicsel-v040-sixel-text-sizing-and-agent-shell/</id>
        
        <content type="html" xml:base="/blog/kitty-graphicsel-v040-sixel-text-sizing-and-agent-shell/">&lt;p&gt;After the &lt;a href=&quot;file:&#x2F;&#x2F;&#x2F;blog&#x2F;kitty-graphics-el-v021-release&quot;&gt;v0.2.1 release&lt;&#x2F;a&gt;, I went quiet for a while. Not because I lost interest, but because I was building the biggest update so far. v0.4.0 brings three major features: Sixel graphics support, the text sizing protocol for org headings, and agent-shell integration.&lt;&#x2F;p&gt;
&lt;p&gt;This post covers everything new in v0.4.0.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;sixel-support&quot;&gt;Sixel Support&lt;&#x2F;h1&gt;
&lt;p&gt;The library no longer requires Kitty. I abstracted the graphics backend so it can speak both the Kitty image protocol and Sixel. Auto-detection happens via DA1 query. If your terminal supports Sixel, kitty-graphics will use it automatically. No configuration needed.&lt;&#x2F;p&gt;
&lt;p&gt;Tested and confirmed working in &lt;code&gt;foot&lt;&#x2F;code&gt;, &lt;code&gt;xterm&lt;&#x2F;code&gt;, &lt;code&gt;Konsole&lt;&#x2F;code&gt;, &lt;code&gt;mlterm&lt;&#x2F;code&gt;, and &lt;code&gt;mintty&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;post&#x2F;kitty-graphicsel-v040-sixel-text-sizing-inline-video-and-agent-shell&#x2F;foot.gif&quot; alt=&quot;img&quot; &#x2F;&gt; l One thing to keep in mind: the Kitty image protocol is still superior in terms of speed and image quality. Kitty gives you truecolor rendering and stateful image management. Sixel tops out at 256 colors and requires re-transmitting the image data on every redraw. If your terminal supports both, prefer Kitty.&lt;&#x2F;p&gt;
&lt;p&gt;The Sixel backend reuses the same overlay system, cache, and refresh cycle as the Kitty backend. All existing features (org inline images, LaTeX previews, doc-view, image-mode, dirvish) work with both protocols.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;text-sizing-protocol-osc-66&quot;&gt;Text Sizing Protocol (OSC 66)&lt;&#x2F;h1&gt;
&lt;p&gt;This one is new territory. We can now render org headings at scaled sizes. &lt;code&gt;* Heading&lt;&#x2F;code&gt; renders at 2x, &lt;code&gt;** Sub&lt;&#x2F;code&gt; at 1.5x, &lt;code&gt;*** Deep&lt;&#x2F;code&gt; at 1.2x. It looks like proper typographic hierarchy, right inside terminal Emacs.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;post&#x2F;kitty-graphicsel-v040-sixel-text-sizing-inline-video-and-agent-shell&#x2F;text-protocol.gif&quot; alt=&quot;img&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The implementation uses OSC 66 escape sequences to tell the terminal to render text at a different scale. Overlays are placed on top of heading lines and emit the scaled text. Folding and unfolding headings works correctly. Scrolling works correctly. The refresh cycle tracks overlay positions and cleans up stale renders.&lt;&#x2F;p&gt;
&lt;p&gt;A preview mode temporarily disables packages that conflict with the overlays (org-modern, org-appear, olivetti, etc.) for clean rendering. You can toggle images while text sizing is active, though not both at the same time yet.&lt;&#x2F;p&gt;
&lt;p&gt;Take this feature with a grain of salt. OSC 66 is very new and there are not many implementations out there. Right now it requires &lt;strong&gt;Kitty &amp;gt;= 0.40.0&lt;&#x2F;strong&gt;, which is the only terminal that implements OSC 66 with scale support.&lt;&#x2F;p&gt;
&lt;p&gt;I will keep improving this. I think it is genuinely great eye candy, and something I had never seen before in a terminal. Someone mentioned it under one of my Reddit threads and I had no idea it existed. If you feel mentioned, thanks.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;agent-shell-support&quot;&gt;agent-shell Support&lt;&#x2F;h1&gt;
&lt;p&gt;Thanks to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Lenbok&quot;&gt;Lenbok&lt;&#x2F;a&gt;, kitty-graphics now works inside &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;Lenbok&#x2F;agent-shell&quot;&gt;agent-shell&lt;&#x2F;a&gt; sessions. Images display correctly in agent-shell buffers. This came in as PR #3.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;bug-fixes-and-polish&quot;&gt;Bug Fixes and Polish&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;Column guard for text sizing to prevent out-of-bounds rendering&lt;&#x2F;li&gt;
&lt;li&gt;CPU optimization: reduced redundant redraws in the text sizing path&lt;&#x2F;li&gt;
&lt;li&gt;Preview mode stability improvements&lt;&#x2F;li&gt;
&lt;li&gt;Sixel backend parity: better interop with the Kitty protocol path&lt;&#x2F;li&gt;
&lt;li&gt;Skip heading overlay emission when a heading is folded to the same visual line (prevents ghost glyphs)&lt;&#x2F;li&gt;
&lt;li&gt;Switched to ECH erase + pre-erase pattern (credit: mdfried) for cleaner column clearing&lt;&#x2F;li&gt;
&lt;li&gt;Force redisplay before position queries to fix initial image placement&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;what-comes-next&quot;&gt;What Comes Next&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;tmux-support&quot;&gt;tmux support&lt;&#x2F;h2&gt;
&lt;p&gt;tmux already supports Sixel, so the Sixel backend will work there out of the box. There is also an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tmux&#x2F;tmux&#x2F;tree&#x2F;ta&#x2F;kitty-img&quot;&gt;in-progress branch&lt;&#x2F;a&gt; adding Kitty image protocol support to tmux. If you already use Kitty directly, I would stick with it. The Kitty protocol gives you stateful image management, truecolor rendering, and a smoother experience overall.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;package-renaming&quot;&gt;Package renaming?&lt;&#x2F;h2&gt;
&lt;p&gt;I am thinking about renaming the project to something like &lt;code&gt;terminal-gfx&lt;&#x2F;code&gt;. We now cover more than one protocol and are starting to stabilize the text protocol as well. This is my first project with people actually using it, so if you have suggestions or feedback, I would love to hear it.&lt;&#x2F;p&gt;
&lt;p&gt;If I do rename it, I will make sure your existing configuration does not break. Shoutouts to neovim and its stable ecosystem &lt;em&gt;hust hust&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;installation&quot;&gt;Installation&lt;&#x2F;h1&gt;
&lt;p&gt;Drop &lt;code&gt;kitty-graphics.el&lt;&#x2F;code&gt; into your load path and enable the mode:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;kitty-graphics&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;kitty-graphics-mode &lt;&#x2F;span&gt;&lt;span style=&quot;color: #EF9F76;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Or with &lt;code&gt;use-package&lt;&#x2F;code&gt; and &lt;code&gt;straight.el&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;use-package&lt;&#x2F;span&gt;&lt;span&gt; kitty-graphics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;straight&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;host github &lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;repo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt; &amp;quot;cashmeredev&#x2F;kitty-graphics.el&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;not&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;display-graphic-p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;config&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span&gt;kitty-graphics-mode &lt;&#x2F;span&gt;&lt;span style=&quot;color: #EF9F76;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that the &lt;code&gt;:if&lt;&#x2F;code&gt; guard no longer checks for &lt;code&gt;KITTY_PID&lt;&#x2F;code&gt; since Sixel terminals are now supported too.&lt;&#x2F;p&gt;
&lt;p&gt;If you run into issues or have feature requests, open an issue on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cashmeredev&#x2F;kitty-graphics.el&#x2F;issues&quot;&gt;GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Release: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cashmeredev&#x2F;kitty-graphics.el&#x2F;releases&#x2F;tag&#x2F;v0.4.0&quot;&gt;v0.4.0 on GitHub&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;post&#x2F;kitty-graphicsel-v040-sixel-text-sizing-inline-video-and-agent-shell&#x2F;text-protocol.gif&quot; alt=&quot;img&quot; &#x2F;&gt; &lt;img src=&quot;&#x2F;images&#x2F;post&#x2F;kitty-graphicsel-v040-sixel-text-sizing-inline-video-and-agent-shell&#x2F;foot.gif&quot; alt=&quot;img&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>kitty-graphics.el v0.2.1: Org Inline Fix, LaTeX Previews, PDF Viewing and Dirvish</title>
        <published>2026-02-27T00:00:00+00:00</published>
        <updated>2026-02-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/kitty-graphics-el-v021-release/"/>
        <id>/blog/kitty-graphics-el-v021-release/</id>
        
        <content type="html" xml:base="/blog/kitty-graphics-el-v021-release/">&lt;p&gt;Three days after the &lt;a href=&quot;file:&#x2F;&#x2F;&#x2F;blog&#x2F;kitty-graphics-el-images-in-terminal-emacs&quot;&gt;initial release&lt;&#x2F;a&gt;, I published v0.2.1. The first version got a warm reception on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;emacs&#x2F;comments&#x2F;1rd7qxw&#x2F;kittygraphicsel_inline_images_in_terminal_emacs&#x2F;&quot;&gt;r&#x2F;emacs&lt;&#x2F;a&gt; and people immediately started asking for things: LaTeX fragment previews, doc-view support, images hiding when headings are folded. I went ahead and built all of that.&lt;&#x2F;p&gt;
&lt;p&gt;This post covers everything new in v0.2.1.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;org-inline-images&quot;&gt;Org Inline Images&lt;&#x2F;h1&gt;
&lt;p&gt;The core feature from the first release, now more robust. Toggle inline images with &lt;code&gt;C-c C-x C-v&lt;&#x2F;code&gt;. File links, attachment links, and relative paths all work.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;posts&#x2F;kitty-graphics-el-v021-release&#x2F;inline.gif&quot; alt=&quot;img&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;latex-fragment-preview&quot;&gt;LaTeX Fragment Preview&lt;&#x2F;h1&gt;
&lt;p&gt;This was one of the most requested features. You can now preview LaTeX fragments directly in org-mode with &lt;code&gt;C-c C-x C-l&lt;&#x2F;code&gt;, the same keybinding you already know. The fragments are rendered via &lt;code&gt;dvipng&lt;&#x2F;code&gt; and displayed inline through the Kitty graphics protocol. No GUI frame required.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;posts&#x2F;kitty-graphics-el-v021-release&#x2F;latex-inline.gif&quot; alt=&quot;img&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It works by advising &lt;code&gt;org-latex-preview&lt;&#x2F;code&gt; and &lt;code&gt;org--make-preview-overlay&lt;&#x2F;code&gt; to intercept the image generation pipeline. Org&#x27;s LaTeX rendering doesn&#x27;t actually need a GUI. It shells out to &lt;code&gt;dvipng=&#x2F;=dvisvgm&lt;&#x2F;code&gt;, so all we do is bypass the &lt;code&gt;display-graphic-p&lt;&#x2F;code&gt; guard and feed the resulting PNGs into the Kitty protocol.&lt;&#x2F;p&gt;
&lt;p&gt;One annoying edge case: terminal Emacs sometimes reports &lt;code&gt;unspecified-fg&lt;&#x2F;code&gt; for face colors, which breaks org&#x27;s color formatting. The advice forces concrete foreground&#x2F;background colors so the LaTeX output doesn&#x27;t come out invisible.&lt;&#x2F;p&gt;
&lt;p&gt;Clear previews with &lt;code&gt;C-u C-c C-x C-l&lt;&#x2F;code&gt; (region) or &lt;code&gt;C-u C-u C-c C-x C-l&lt;&#x2F;code&gt; (buffer).&lt;&#x2F;p&gt;
&lt;h1 id=&quot;doc-view-integration&quot;&gt;doc-view Integration&lt;&#x2F;h1&gt;
&lt;p&gt;PDFs, DVI and PostScript files now render in the terminal via doc-view. Page navigation works as expected. &lt;code&gt;n=&#x2F;=p&lt;&#x2F;code&gt; to flip pages. Zoom works too: &lt;code&gt;+&lt;&#x2F;code&gt; to zoom in, &lt;code&gt;-&lt;&#x2F;code&gt; to zoom out, &lt;code&gt;0&lt;&#x2F;code&gt; to reset. Each page is rendered centered in the window.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;posts&#x2F;kitty-graphics-el-v021-release&#x2F;pdf.gif&quot; alt=&quot;img&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The implementation patches &lt;code&gt;doc-view-mode-p&lt;&#x2F;code&gt; to bypass the GUI check (same approach as LaTeX, &lt;code&gt;cl-letf&lt;&#x2F;code&gt; to temporarily make &lt;code&gt;display-graphic-p&lt;&#x2F;code&gt; return &lt;code&gt;t&lt;&#x2F;code&gt;), and &lt;code&gt;doc-view-insert-image&lt;&#x2F;code&gt; to display the page PNG via Kitty graphics instead of an Emacs image spec.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;image-mode&quot;&gt;Image-Mode&lt;&#x2F;h1&gt;
&lt;p&gt;Image-mode now centers images in the window and supports zoom controls:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;+&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;=&lt;&#x2F;code&gt; to zoom in&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;-&lt;&#x2F;code&gt; to zoom out&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;0&lt;&#x2F;code&gt; to reset to 1:1&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;posts&#x2F;kitty-graphics-el-v021-release&#x2F;image.gif&quot; alt=&quot;img&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;To avoid conflicts with evil-mode (which was a problem in the first release), the terminal image viewer now uses its own &lt;code&gt;kitty-gfx-image-mode&lt;&#x2F;code&gt; major mode instead of hijacking &lt;code&gt;image-mode&lt;&#x2F;code&gt; directly. This means evil-collection&#x27;s image-mode bindings, which call native image functions that don&#x27;t work in terminal, don&#x27;t interfere.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;dirvish-integration&quot;&gt;Dirvish Integration&lt;&#x2F;h1&gt;
&lt;p&gt;Image previews in dirvish now work natively in the terminal. The package registers a &lt;code&gt;kitty-image&lt;&#x2F;code&gt; preview dispatcher that renders images in the preview pane as you navigate. No extra configuration needed. If &lt;code&gt;kitty-graphics-mode&lt;&#x2F;code&gt; is enabled and dirvish is loaded, it just works.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;posts&#x2F;kitty-graphics-el-v021-release&#x2F;dirvish-previews.gif&quot; alt=&quot;img&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;images-hide-when-org-headings-are-collapsed&quot;&gt;Images Hide When Org Headings Are Collapsed&lt;&#x2F;h1&gt;
&lt;p&gt;This was the first bug report on the initial release and arguably the most annoying one. Images stayed visible when you folded a heading, floating in space disconnected from their context.&lt;&#x2F;p&gt;
&lt;p&gt;The fix checks both &lt;code&gt;org-fold&lt;&#x2F;code&gt; (org 9.6+, text-property based) and legacy overlay-based invisibility. When a heading is collapsed, image overlays inside the fold have their terminal placements deleted. When you unfold, the refresh cycle re-places them. It also correctly ignores cosmetic invisibility like hidden link brackets (&lt;code&gt;org-link&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h1 id=&quot;robustness-overhaul&quot;&gt;Robustness Overhaul&lt;&#x2F;h1&gt;
&lt;p&gt;The internal machinery got a complete overhaul. None of this changes user-facing behavior, but it makes the whole system significantly more reliable.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;lru-image-cache&quot;&gt;LRU Image Cache&lt;&#x2F;h2&gt;
&lt;p&gt;The old cache was an unbounded hash table. Every image ever displayed stayed in terminal memory forever. Now there&#x27;s a proper LRU cache with a configurable size limit (&lt;code&gt;kitty-gfx-cache-size&lt;&#x2F;code&gt;, default 64). When the cache is full, the least recently used image gets evicted and its terminal data deleted.&lt;&#x2F;p&gt;
&lt;p&gt;The cache also no longer stores image dimensions. Dimensions are computed fresh each time from the pixel size and current cell metrics. This means zooming, resizing windows, or viewing the same image in different contexts (org-mode vs. image-mode vs. dired) always gets correct dimensions instead of stale cached values.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;less-flicker&quot;&gt;Less Flicker&lt;&#x2F;h2&gt;
&lt;p&gt;Buffer and window changes used to delete &lt;em&gt;all&lt;&#x2F;em&gt; placements and re-create them from scratch. This caused visible flicker, especially when switching between buffers in a split. Now:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Buffer change&lt;&#x2F;em&gt;: only deletes placements for buffers that are no longer visible in any window. Visible buffers just get their position caches invalidated.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Window change&lt;&#x2F;em&gt;: invalidates position caches and cell pixel size, but doesn&#x27;t delete anything. The refresh cycle handles re-placement.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Leading-edge debounce&lt;&#x2F;em&gt;: the first refresh fires immediately (after redisplay), then enters a cooldown period. Calls during cooldown are suppressed but flagged. When the cooldown expires, one trailing refresh fires to capture the final state.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;overflow-protection&quot;&gt;Overflow Protection&lt;&#x2F;h2&gt;
&lt;p&gt;Images that would extend past the bottom edge of the window are now hidden instead of placed. Before this, a tall image near the bottom of the screen would overflow into whatever was below the window, causing visual corruption.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;safer-cleanup&quot;&gt;Safer Cleanup&lt;&#x2F;h2&gt;
&lt;p&gt;Killing a buffer now checks whether other buffers still reference the same image ID before deleting the terminal-side image data. This prevents breaking shared images, for example having the same file open in org-mode and image-mode simultaneously.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;everything-else&quot;&gt;Everything Else&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;convert-to-png&lt;&#x2F;code&gt; returns &lt;code&gt;nil&lt;&#x2F;code&gt; on failure instead of passing the original non-PNG file to the terminal&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;unwind-protect&lt;&#x2F;code&gt; around temp file creation in all display paths&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;ignore-errors&lt;&#x2F;code&gt; around every &lt;code&gt;send-string-to-terminal&lt;&#x2F;code&gt; call&lt;&#x2F;li&gt;
&lt;li&gt;Cell pixel size re-queried on window resize&lt;&#x2F;li&gt;
&lt;li&gt;Dead overlay pruning in the refresh cycle&lt;&#x2F;li&gt;
&lt;li&gt;Millisecond-precision debug logging (enable with &lt;code&gt;kitty-gfx-debug&lt;&#x2F;code&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;installation&quot;&gt;Installation&lt;&#x2F;h1&gt;
&lt;p&gt;Drop &lt;code&gt;kitty-graphics.el&lt;&#x2F;code&gt; into your load path and enable the mode:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;kitty-graphics&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;kitty-graphics-mode &lt;&#x2F;span&gt;&lt;span style=&quot;color: #EF9F76;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Or with &lt;code&gt;use-package&lt;&#x2F;code&gt; and &lt;code&gt;straight.el&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;use-package&lt;&#x2F;span&gt;&lt;span&gt; kitty-graphics&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;straight&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;host github &lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt;repo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt; &amp;quot;cashmeredev&#x2F;kitty-graphics.el&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;and&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;not&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;display-graphic-p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;getenv&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt; &amp;quot;KITTY_PID&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span&gt;config&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span&gt;kitty-graphics-mode &lt;&#x2F;span&gt;&lt;span style=&quot;color: #EF9F76;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;with-eval-after-load&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;dired&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;define-key&lt;&#x2F;span&gt;&lt;span&gt; dired-mode-map &lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;kbd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt; &amp;quot;P&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;) #&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;kitty-gfx-dired-preview&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you run into issues or have feature requests, open an issue on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cashmeredev&#x2F;kitty-graphics.el&#x2F;issues&quot;&gt;GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Release: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cashmeredev&#x2F;kitty-graphics.el&#x2F;releases&#x2F;tag&#x2F;v0.2.1&quot;&gt;v0.2.1 on GitHub&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>kitty-graphics.el — Images in Terminal Emacs</title>
        <published>2026-02-24T00:00:00+00:00</published>
        <updated>2026-02-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/kitty-graphics-el-images-in-terminal-emacs/"/>
        <id>/blog/kitty-graphics-el-images-in-terminal-emacs/</id>
        
        <content type="html" xml:base="/blog/kitty-graphics-el-images-in-terminal-emacs/">&lt;p&gt;I had this thought for months about whether it would be possible to display images in terminal Emacs using the Kitty graphics protocol. So I finally sat down and tried it out.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cashmeredev&#x2F;kitty-graphics.el&quot;&gt;kitty-graphics.el&lt;&#x2F;a&gt; renders images directly in &lt;code&gt;emacs -nw&lt;&#x2F;code&gt; using direct placements. The whole thing is pure Emacs Lisp — no patches, no forks, no C modules. Just a single &lt;code&gt;.el&lt;&#x2F;code&gt; file you drop into your config and it works.&lt;&#x2F;p&gt;
&lt;p&gt;Images are transmitted once to the terminal, then positioned at overlay screen coordinates after each redisplay. They scroll with text, survive buffer switches, and work in split windows.&lt;&#x2F;p&gt;
&lt;p&gt;It integrates with:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;org-mode&lt;&#x2F;em&gt; — inline images with &lt;code&gt;C-c C-x C-v&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;image-mode&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;eww &#x2F; mu4e &#x2F; gnus&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;dired&lt;&#x2F;em&gt; and &lt;em&gt;dirvish&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;No external dependencies beyond built-in &lt;code&gt;cl-lib&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I should mention that I used Claude quite a bit for this. I totally get that the current AI slop is exhausting, but I&#x27;ve been wanting this feature for a long time and I know other people have too. So idk, I hope it&#x27;s useful to someone, even if just as a reference.&lt;&#x2F;p&gt;
&lt;p&gt;Repo: [[&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cashmeredev&#x2F;kitty-graphics.el&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;cashmeredev&#x2F;kitty-graphics.el&lt;&#x2F;a&gt;]]&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Messing around with Nix, Emacs and EAF-Framework</title>
        <published>2026-02-19T00:00:00+00:00</published>
        <updated>2026-02-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/messing-around-with-nix-emacs-and-eaf-framework/"/>
        <id>/blog/messing-around-with-nix-emacs-and-eaf-framework/</id>
        
        <content type="html" xml:base="/blog/messing-around-with-nix-emacs-and-eaf-framework/">&lt;h1 id=&quot;disclaimer&quot;&gt;DISCLAIMER&lt;&#x2F;h1&gt;
&lt;p&gt;Please do not continue on reading if you are against:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Integration of third-party languages into Emacs&lt;&#x2F;li&gt;
&lt;li&gt;Bloat&#x2F;Unnecessary integrations into Emacs&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;FUN!!&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;takeaways&quot;&gt;Takeaways&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;Let nixpkgs do the heavy lifting and handle the correct way of packaging complex packages such as &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;emacs-eaf&#x2F;emacs-application-framework&quot;&gt;emacs-eaf&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Small emacs-lisp snippet to integrate and handle eaf buffers in a more flexible way&lt;&#x2F;li&gt;
&lt;li&gt;Small showcase&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If you could not care less about my personal &lt;em&gt;why&lt;&#x2F;em&gt;, then feel free to move on to the .&lt;&#x2F;p&gt;
&lt;h1 id=&quot;backstory&quot;&gt;Backstory&lt;&#x2F;h1&gt;
&lt;p&gt;I think the vast majority of us do agree, that Emacs is one if not the most extensible playground, as I like to call it, somebody can experience.&lt;&#x2F;p&gt;
&lt;p&gt;In my case, it was &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;emacs-exwm&#x2F;exwm&quot;&gt;exwm&lt;&#x2F;a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;emacs-eaf&#x2F;emacs-application-framework&quot;&gt;emacs-eaf&lt;&#x2F;a&gt; showcased in this &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=z9W0pnShEW&quot;&gt;video&lt;&#x2F;a&gt;. Now after integrating Emacs not only into my developer workflow, but more as a tool I just love to use from day to day, I made the learning that it&#x27;s less of &lt;em&gt;how&lt;&#x2F;em&gt; much can this editor handle until it breaks, but more of a &lt;em&gt;how can&lt;&#x2F;em&gt; this environment benefit me in my day to day challenges. I still think it&#x27;s a fun way to interact with Emacs, maybe extend it in ways you cannot with emacs-lisp alone or to just experience more possibilities of Emacs extensibility beyond the ones you currently know.&lt;&#x2F;p&gt;
&lt;p&gt;Nonetheless, I love to mess, try and configure Emacs. If something does break, doesn&#x27;t matter as everything is version controlled. This statement is true until the point where third-party dependencies come my way. That&#x27;s the moment, where I utilize Nix to profit from declarative packaging and then configure it on my side.&lt;&#x2F;p&gt;
&lt;p&gt;Now as cool and fun as emacs-eaf does look, the installation process is the complete opposite.&lt;&#x2F;p&gt;
&lt;p&gt;Digging into nixpkgs, you may realize that &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;NixOS&#x2F;nixpkgs&#x2F;blob&#x2F;nixos-unstable&#x2F;pkgs&#x2F;applications&#x2F;editors&#x2F;emacs&#x2F;elisp-packages&#x2F;manual-packages&#x2F;eaf&#x2F;package.nix&quot;&gt;eaf&lt;&#x2F;a&gt; is also packaged.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;nix-letting-nixpkgs-do-the-heavy-lifting&quot;&gt;Nix, letting nixpkgs do the heavy lifting&lt;&#x2F;h2&gt;
&lt;p&gt;The whole point of using Nix here is to never think about EAF&#x27;s dependency hell yourself. Python, Qt, DBus wiring, nixpkgs takes care of all of it. You just declare what you want.&lt;&#x2F;p&gt;
&lt;p&gt;Inside my Emacs derivation I override &lt;code&gt;emacs-application-framework&lt;&#x2F;code&gt; with the specific apps I care about:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;nix&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;myEmacs = pkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;emacs-gtk&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;pkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;withPackages&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EA999C;font-style: italic;&quot;&gt;epkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;: [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  epkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;mu4e&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  epkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;offlineimap&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  epkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;pdf-tools&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  epkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;nushell-ts-mode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span&gt;epkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;emacs-application-framework&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;override&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;    enabledApps&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      epkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eaf-browser&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      epkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;eaf-pyqterminal&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      eaf-auralis&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;    ];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;  })&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;])&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s it. No &lt;code&gt;install-eaf.py&lt;&#x2F;code&gt;, no manual &lt;code&gt;pip install&lt;&#x2F;code&gt;, no chasing Qt versions. The &lt;code&gt;override&lt;&#x2F;code&gt; mechanism lets you pick exactly which EAF apps get built and bundled. Everything else, Python environment, shared libraries, wrapper scripts, is handled by the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;NixOS&#x2F;nixpkgs&#x2F;blob&#x2F;nixos-unstable&#x2F;pkgs&#x2F;applications&#x2F;editors&#x2F;emacs&#x2F;elisp-packages&#x2F;manual-packages&#x2F;eaf&#x2F;package.nix&quot;&gt;package expression&lt;&#x2F;a&gt; upstream.&lt;&#x2F;p&gt;
&lt;p&gt;Rebuild, switch, done. If it breaks, roll back one generation.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;emacs-loading-eaf-and-wiring-up-c-spc&quot;&gt;Emacs, loading EAF and wiring up &lt;code&gt;C-SPC&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Now on the Emacs side, the packages are on the &lt;code&gt;load-path&lt;&#x2F;code&gt; thanks to Nix, but we still need to &lt;code&gt;require&lt;&#x2F;code&gt; them at the right time. EAF needs a graphical display, so loading it during a headless daemon start will crash. The solution is a small init function that defers loading until a frame actually exists:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;setq eaf-pyqterminal-font-size &lt;&#x2F;span&gt;&lt;span style=&quot;color: #EF9F76;&quot;&gt;24&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      eaf-pyqterminal-refresh-ms &lt;&#x2F;span&gt;&lt;span style=&quot;color: #EF9F76;&quot;&gt;17&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      eaf-pyqterminal-font-family &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;&amp;quot;Maple Mono NF&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      eaf-pyqterminal-cursor-type &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;&amp;quot;bar&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      eaf-pyqterminal-cursor-size &lt;&#x2F;span&gt;&lt;span style=&quot;color: #EF9F76;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;defvar&lt;&#x2F;span&gt;&lt;span&gt; my&#x2F;eaf-loaded&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E78284;&quot;&gt; nil&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;  &amp;quot;Non-nil after EAF has been successfully loaded.&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;defun&lt;&#x2F;span&gt;&lt;span&gt; my&#x2F;eaf-init&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; ()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;  &amp;quot;Load EAF and its apps, but only when a graphical display is available.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;Errors are caught so a broken EAF never kills the Emacs session.&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;when&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;and&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;display-graphic-p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;not&lt;&#x2F;span&gt;&lt;span&gt; my&#x2F;eaf-loaded&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;condition-case&lt;&#x2F;span&gt;&lt;span&gt; err&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;progn&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;eaf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;eaf-browser&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;eaf-pyqterminal&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;eaf-auralis&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;font-style: italic;&quot;&gt;          ;; Evil leader integration&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;when&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;featurep&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;evil&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;require&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;eaf-evil&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span&gt;setq eaf-evil-leader-key &lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;&amp;quot;C-SPC&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span&gt;leader-km &lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;when&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;boundp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;general-override-mode-map&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;                               (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;lookup-key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;                                (&lt;&#x2F;span&gt;&lt;span&gt;evil-get-auxiliary-keymap&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                 general-override-mode-map &lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;normal&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;                                (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;kbd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt; &amp;quot;SPC&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;              (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;when&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;keymapp&lt;&#x2F;span&gt;&lt;span&gt; leader-km&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;                (&lt;&#x2F;span&gt;&lt;span&gt;setq eaf-evil-leader-keymap leader-km&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;          (&lt;&#x2F;span&gt;&lt;span&gt;setq my&#x2F;eaf-loaded t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;          (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt; &amp;quot;EAF loaded successfully.&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;      (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;error&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;       (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt; &amp;quot;EAF failed to load: %s&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;error-message-string&lt;&#x2F;span&gt;&lt;span&gt; err&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;))))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;if&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;daemonp&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;add-hook&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;server-after-make-frame-hook&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; #&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;my&#x2F;eaf-init&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;add-hook&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;after-init-hook&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; #&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;my&#x2F;eaf-init&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The key bit is the &lt;code&gt;C-SPC&lt;&#x2F;code&gt; binding. EAF buffers live in their own Qt world, normal Evil keybindings don&#x27;t reach them. By setting &lt;code&gt;eaf-evil-leader-key&lt;&#x2F;code&gt; to &lt;code&gt;C-SPC&lt;&#x2F;code&gt; and pointing &lt;code&gt;eaf-evil-leader-keymap&lt;&#x2F;code&gt; at your existing leader map, you get your full &lt;code&gt;SPC&lt;&#x2F;code&gt; menu inside EAF buffers via &lt;code&gt;C-SPC&lt;&#x2F;code&gt;. Buffer switching, perspectives, whatever you bound under your leader, it all just works.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;condition-case&lt;&#x2F;code&gt; wrapper is not optional paranoia. EAF depends on a living Python process. If something in the Nix build changed or Qt decides to be Qt, you don&#x27;t want your entire init to bail. This way Emacs starts fine and you get a message telling you what went wrong.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;crash-cleanup&quot;&gt;Crash cleanup&lt;&#x2F;h2&gt;
&lt;p&gt;One thing that annoyed me: when the EAF Python process dies (and it will, eventually), it leaves behind dead buffers that just sit there doing nothing. A small process sentinel fixes that:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;advice-add&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;eaf--start-process&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt; :&lt;&#x2F;span&gt;&lt;span&gt;after&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;lambda&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E78284;&quot;&gt;&amp;amp;rest&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EA999C;font-style: italic;&quot;&gt; _&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;              (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;when-let*&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span&gt;proc &lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;get-process&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt; &amp;quot;eaf&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;                (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;set-process-sentinel&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                 proc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;                 (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;lambda&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EA999C;font-style: italic;&quot;&gt;process event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;                   (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;when&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;memq&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;process-status&lt;&#x2F;span&gt;&lt;span&gt; process&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;) &amp;#39;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;exit&lt;&#x2F;span&gt;&lt;span&gt; signal&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;                     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;message&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt; &amp;quot;EAF process terminated: %s&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;string-trim&lt;&#x2F;span&gt;&lt;span&gt; event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;                     (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;dolist&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span&gt;buf &lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;buffer-list&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;                       (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;when&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt;and&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;buffer-live-p&lt;&#x2F;span&gt;&lt;span&gt; buf&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;                                  (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;with-current-buffer&lt;&#x2F;span&gt;&lt;span&gt; buf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;                                    (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;derived-mode-p&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;eaf-mode&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;                         (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;with-current-buffer&lt;&#x2F;span&gt;&lt;span&gt; buf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;                           (&lt;&#x2F;span&gt;&lt;span&gt;let&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;inhibit-read-only&lt;&#x2F;span&gt;&lt;span&gt; t&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;                             (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;erase-buffer&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;                             (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;insert&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;format&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt; &amp;quot;EAF process crashed: %s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;\&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;nRe-open this buffer to restart.&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;                                             (&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;string-trim&lt;&#x2F;span&gt;&lt;span&gt; event&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;)))))))))))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Instead of stale frozen buffers, you get a clear message and can just reopen.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;showcase&quot;&gt;Showcase&lt;&#x2F;h1&gt;
&lt;p&gt;With all of that in place, you end up with:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;eaf-open-browser&lt;&#x2F;code&gt; a full Chromium-based browser inside an Emacs buffer&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;eaf-open-pyqterminal&lt;&#x2F;code&gt; a fast Qt terminal emulator, also inside a buffer&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;C-SPC&lt;&#x2F;code&gt; inside any EAF buffer drops you back into your leader keymap&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Nothing here is something you &lt;em&gt;need&lt;&#x2F;em&gt;. But if you enjoy pushing Emacs into weird corners and letting Nix clean up after you, it&#x27;s a fun ride.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Cyberbridge announcement</title>
        <published>2026-01-29T00:00:00+00:00</published>
        <updated>2026-01-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/cyberbridge-announcement/"/>
        <id>/blog/cyberbridge-announcement/</id>
        
        <content type="html" xml:base="/blog/cyberbridge-announcement/">&lt;p&gt;I have finally published the first version of my Cyberbridge wiki. It&#x27;s a curated collection of applications, tools, and web services that show how I was able to use a Blackberry Classic until today.&lt;&#x2F;p&gt;
&lt;p&gt;Official documentation: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cyberbridge.cashmere.rs&#x2F;&quot;&gt;https:&#x2F;&#x2F;cyberbridge.cashmere.rs&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Git repository with all the .md files in case you want to read them as files: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git.sr.ht&#x2F;~cashmere&#x2F;cyberbridge&quot;&gt;https:&#x2F;&#x2F;git.sr.ht&#x2F;~cashmere&#x2F;cyberbridge&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I would love to get some feedback, criticism, etc.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Cyberbridge Part 1: Bitlbee - the gateway to social media</title>
        <published>2025-12-11T00:00:00+00:00</published>
        <updated>2025-12-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/cyberbridge-part-1-bitlbee-the-gateway-to-social-media/"/>
        <id>/blog/cyberbridge-part-1-bitlbee-the-gateway-to-social-media/</id>
        
        <content type="html" xml:base="/blog/cyberbridge-part-1-bitlbee-the-gateway-to-social-media/">&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a id=&quot;orgb4f9f7b&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bitlbee&quot;&gt;Bitlbee&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.bitlbee.org&#x2F;main.php&#x2F;news.r.html&quot;&gt;Bitlbee&lt;&#x2F;a&gt; is a messaging gateway with its initial release on &lt;em&gt;9 August 2002&lt;&#x2F;em&gt;. It has been developed for over two decades; while I assume the current development is mostly maintenance, it&#x27;s fully featured. It&#x27;s also really awesome that such a niche software has been taken care of for such a long time.&lt;&#x2F;p&gt;
&lt;p&gt;Bitlbee works on your host the same as it does on a VPS. For demonstration, I will set it up on my localhost and then connect from my BlackBerry to my localhost to interact with Bitlbee. I also suggest doing the same to avoid the risk of leaking any information by accident and for security reasons. I will do a follow-up on how to self-host it on a cheap VPS or access it over a public instance in general.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org67aabcf&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;irc&quot;&gt;IRC&lt;&#x2F;h2&gt;
&lt;p&gt;Bitlbee itself is based on the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;IRC&quot;&gt;Internet Relay Chat&lt;&#x2F;a&gt;, better known as IRC. IRC was established in 1988, has its own history, and, although it has lost popularity over time, there are many ways, clients, and devices that are able to establish a connection to an IRC network.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;orgeae7a83&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;xmpp&quot;&gt;XMPP&lt;&#x2F;h2&gt;
&lt;p&gt;Now the last network introduced by Bitlbee is the eXtensible Messaging and Presence Protocol. To keep it short, XMPP is the backbone of the most well-known messaging platform, you guessed it, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;WhatsApp#Technical&quot;&gt;WhatsApp&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org7772ba0&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;example&quot;&gt;Example&lt;&#x2F;h2&gt;
&lt;p&gt;Now let&#x27;s set IRC, Bitlbee, XMPP, and your device in action to get a better understanding:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;bitlbee-architecture.png&quot; alt=&quot;img&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Your device will establish a connection to the gateway through IRC. In my case, my device is a BlackBerry Classic. I use Revolution IRC.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Connection established! Set up the service according to your needs. For demonstration, I am going to set up Discord and send some messages to [[&amp;lt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;discord.gg&#x2F;JdWtYJ6PfM&quot;&gt;https:&#x2F;&#x2F;discord.gg&#x2F;JdWtYJ6PfM&lt;&#x2F;a&gt;&amp;gt;][Laundry Mat Linux Shack]]. The Discord service does not have native integration in Bitlbee; it&#x27;s built on XMPP, as are many more plugins you will connect to in the near future.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Let&#x27;s have fun and brag in front of people about having the same or similar feature parity as them. While I do maybe brag sometimes, it&#x27;s very often a topic. A great way to shine with your geekiness and knowledge!&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;a id=&quot;orgeb9763f&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;demo&quot;&gt;Demo&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a id=&quot;org9df60a4&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;&#x2F;h2&gt;
&lt;p&gt;Now here comes the part I have the most concerns about. While Bitlbee states they support almost every Linux distribution, I cannot guarantee the extent to which you may or may not face issues. Considering the project&#x27;s age and that it is written in the C programming language, which is known for running on almost any device, I think it&#x27;s unlikely you&#x27;ll encounter issues.&lt;&#x2F;p&gt;
&lt;p&gt;Still, I suggest consulting your platform&#x27;s wiki or, of course, the original wiki from Bitlbee.&lt;&#x2F;p&gt;
&lt;p&gt;If you still have issues or have specific questions, do not hesitate to send me a message!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;repology.org&quot;&gt;Repology&lt;&#x2F;a&gt; is another great way to check the availability on most relevant distros. As for &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;repology.org&#x2F;project&#x2F;bitlbee&#x2F;versions&quot;&gt;bitlbee&lt;&#x2F;a&gt;, it looks very promising, with up-to-date support for Arch, Fedora, and Debian&#x2F;Ubuntu. We also have support for Alpine. Alpine Linux is always good to keep in mind, as it comes with very low resource usage, is utilized for many Docker images, and, if you own an Android phone, is the distribution powering Termux, which enables you to run Linux with its great advantages on your phone. And yes, of course, you could utilize your phone to host Bitlbee.&lt;&#x2F;p&gt;
&lt;p&gt;If you currently run Windows, I would take a look at WSL2.&lt;&#x2F;p&gt;
&lt;p&gt;I run NixOS, which offers native integration. Feel free to use the following configuration if you do too.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;orge597cb6&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;discord&quot;&gt;Discord&lt;&#x2F;h3&gt;
&lt;p&gt;Taking a look at the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.bitlbee.org&#x2F;&quot;&gt;wiki&lt;&#x2F;a&gt; for Discord, you will realize there are two services for Discord. While the native service is not maintained anymore, the other one is supported through libpurple, which is basically XMPP. Bitlbee &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.bitlbee.org&#x2F;HowtoPurple&quot;&gt;explains&lt;&#x2F;a&gt; some more details about these types of services.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org015aae1&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;nixos&quot;&gt;NixOS&lt;&#x2F;h3&gt;
&lt;p&gt;{ pkgs, … }: { services.bitlbee = { enable = true; interface = &quot;0.0.0.0&quot;; libpurple&lt;sub&gt;plugins&lt;&#x2F;sub&gt; = [ pkgs.pidginPackages.purple-discord ]; }; networking.firewall.allowedTCPPorts = [ 6667 ]; }&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org49d1844&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;connecting-to-bitlbee&quot;&gt;Connecting to bitlbee&lt;&#x2F;h2&gt;
&lt;p&gt;To connect to bitlbee you will need any IRC client. In this section I will use &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;MCMrARM&#x2F;revolution-irc&quot;&gt;RevolutionIRC&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The following two images show how I configured RevolutionIRC to connect to my workstation:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;revolutionirc-1.jpg&quot; alt=&quot;img&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;revolutionirc-2.jpg&quot; alt=&quot;img&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org6cfbd29&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;first-setup&quot;&gt;First setup&lt;&#x2F;h2&gt;
&lt;p&gt;Bitlbee itself has a very extensive &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.bitlbee.org&#x2F;user-guide.html&quot;&gt;user guide&lt;&#x2F;a&gt;. I will keep things short, show you the required commands, and explain what they do or what they are for. There is also this &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=juGVWaQ6t0U&quot;&gt;YouTube video&lt;&#x2F;a&gt; which helped me a lot in the beginning.&lt;&#x2F;p&gt;
&lt;div class=&quot;NOTE&quot; id=&quot;org32a8311&quot;&gt;
&lt;p&gt;
It&#x27;s also helpful to have another IRC client on your desktop alongside, as typing or copy-pasting text to and from the BlackBerry is often fiddly.
&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Once connected to the bitlbee network, you will need to register your user. Adjust &lt;code&gt;mysecurepass&lt;&#x2F;code&gt; to the password you would like.&lt;&#x2F;p&gt;
&lt;p&gt;register mysecurepass&lt;&#x2F;p&gt;
&lt;p&gt;Bitlbee will then log you in instantly. If you want to connect from another device with the same user, you will need to identify yourself with the following command:&lt;&#x2F;p&gt;
&lt;p&gt;identify user mysecurepass&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;orgd9520b5&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;setting-up-your-discord-account-and-connecting-to-it&quot;&gt;Setting up your Discord account and connecting to it&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Add your email to the &lt;code&gt;eionrobb-discord&lt;&#x2F;code&gt; plugin&lt;&#x2F;p&gt;
&lt;p&gt;account add eionrobb-discord your@email.com&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Set your personal Discord token in bitlbee:&lt;&#x2F;p&gt;
&lt;p&gt;account eionrobb-discord set token your long token&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Here is a short &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=GUqSNoJ28aU&quot;&gt;guide&lt;&#x2F;a&gt; on how to get the token. Please be careful, as this token grants anyone full access to your Discord account.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Set your Discord password&lt;&#x2F;p&gt;
&lt;p&gt;account eionrobb-discord set password yourdiscordpass&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Save your current configuration&lt;&#x2F;p&gt;
&lt;p&gt;save&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Connect to Discord&lt;&#x2F;p&gt;
&lt;p&gt;account on&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;From here you should be good to go. Plugin-specific configuration can be found on the original &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;EionRobb&#x2F;purple-discord&quot;&gt;purple-discord&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Here is a screenshot of how I sent a message to Discord from my BlackBerry Classic:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;message-sent.jpg&quot; alt=&quot;img&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And that it was also visible from my Discord client on my workstation:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;screenshot.png&quot; alt=&quot;img&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org932dc3b&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;further-notices-on-bitlbee&quot;&gt;Further notices on bitlbee&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a id=&quot;org0c9a25c&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security&quot;&gt;Security&lt;&#x2F;h2&gt;
&lt;p&gt;bitlbee was primarily developed as a messaging relay, with the intention of being able to handle many different users, but in such a way that bitlbee users cannot see each other&#x27;s private messages and groups.&lt;&#x2F;p&gt;
&lt;p&gt;For example, user Bob can connect to bitlbee, and user Alice can too, at the same time.&lt;&#x2F;p&gt;
&lt;p&gt;However, Alice and Bob cannot communicate with each other via bitlbee itself.&lt;&#x2F;p&gt;
&lt;p&gt;bitlbee can run both locally on your computer and on a server. Running it locally is pretty self-explanatory, I think; your attack vector is relatively small.&lt;&#x2F;p&gt;
&lt;p&gt;I will also include this graphic in my guide. The connection from the IRC client running on your phone, e.g., a BlackBerry, can be made with or without a TLS&#x2F;SSL connection. Personally, I&#x27;ve deployed bitlbee on one of my servers with TLS&#x2F;SSL, and everything works great. You can also encrypt each individual chat separately so that the messages on the hard drive itself are unreadable to anyone but you. I haven&#x27;t gone that far yet, though.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org59c8bff&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;configuring-other-plugins&quot;&gt;Configuring other plugins&lt;&#x2F;h2&gt;
&lt;p&gt;Configuring other plugins, networks, and services follows a similar pattern. Once you get along with bitlbee, it&#x27;s easy to add more networks. For example, I had never used the Discord plugin before, though it was somewhat straightforward to set it up.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;orgff84fbc&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;caveats-of-bitlbee&quot;&gt;&quot;Caveats&quot; of bitlbee&lt;&#x2F;h2&gt;
&lt;p&gt;As bitlbee still relies heavily on IRC, sooner or later you may identify some hurdles introduced with IRC. I will add another follow-up on how to fix them and improve your whole experience.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Cyberbridge - your probably coolest and cheapest way to experience a cyberdeck</title>
        <published>2025-12-01T00:00:00+00:00</published>
        <updated>2025-12-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/cyberbridge-your-probably-coolest-and-cheapest-way-to-experience-a-cyberdeck/"/>
        <id>/blog/cyberbridge-your-probably-coolest-and-cheapest-way-to-experience-a-cyberdeck/</id>
        
        <content type="html" xml:base="/blog/cyberbridge-your-probably-coolest-and-cheapest-way-to-experience-a-cyberdeck/">&lt;h1 id=&quot;cyberbridge-your-probably-coolest-and-cheapest-way-to-experience-a-cyberdeck&quot;&gt;Cyberbridge - your probably coolest and cheapest way to experience a cyberdeck&lt;&#x2F;h1&gt;
&lt;h1 id=&quot;introduction&quot;&gt;introduction&lt;&#x2F;h1&gt;
&lt;p&gt;For about two years now, I&#x27;ve developed a curiosity for obsolete technical devices. I enjoy experimenting with them to see if they are truly outdated or if their charm can be made somewhat usable again with a bit of technical know-how and the established programs or protocols that were commonplace in their time.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;blackberry&quot;&gt;Blackberry&lt;&#x2F;h1&gt;
&lt;p&gt;Almost one year after I started to understand the fundamentals of the Internet, I wanted to own a phone with a physical keyboard again.&lt;&#x2F;p&gt;
&lt;p&gt;Not because I was addicted to social media, wanted to reduce screen time, or anything. It was truly out of curiosity, as in late 2024 all the current new and flashy implementations of a somewhat modern phone with a keyboard were already more than obsolete.&lt;&#x2F;p&gt;
&lt;p&gt;Long story short, I got myself a Blackberry KeyOne, and while I enjoyed using it the first couple of months, there were many reasons why this was not the device I desired.&lt;&#x2F;p&gt;
&lt;p&gt;I went down the rabbit hole a bit deeper and reached what I searched for.&lt;&#x2F;p&gt;
&lt;p&gt;Blackberry&#x27;s last attempt to not get drowned by iOS and Android.&lt;&#x2F;p&gt;
&lt;p&gt;The ones which came into my, and maybe even your, target are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Blackberry Q5&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Blackberry Q10&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Blackberry Classic&lt;&#x2F;p&gt;
&lt;p&gt;I got myself the Blackberry Classic for 40 Eddies, and from there began my journey.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;bridges&quot;&gt;Bridges&lt;&#x2F;h1&gt;
&lt;p&gt;Bridges are, for me personally, one of the coolest and most exciting ways of communicating with almost all of my contacts.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s take the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;matrix.org&quot;&gt;matrix.org&lt;&#x2F;a&gt; coolest selling point and why you may consider using it. It gives you the ability to send messages in private conversations and group conversations to WhatsApp, Telegram, Signal, Discord, IRC, and many, many more.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s basically Thunderbird but for real-time communication, where you decide from which client, operating system, terminal-hell, even &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.atari-forum.com&#x2F;viewtopic.php?t=43339&quot;&gt;Amiga&lt;&#x2F;a&gt;-to communicate with your friends, family, and social groups.&lt;&#x2F;p&gt;
&lt;p&gt;As long as you find a sane or even obscure way to get a connection to your main protocol, you are good to go.&lt;&#x2F;p&gt;
&lt;div class=&quot;note&quot; id=&quot;orgbb05b97&quot;&gt;
&lt;p&gt;
Just to get things out of the way.
&lt;&#x2F;p&gt;
&lt;p&gt;
Two things to consider if you are interested in experimenting with this topic.
&lt;&#x2F;p&gt;
&lt;ol class=&quot;org-ol&quot;&gt;
&lt;li&gt;There is always a risk of getting rate-limited or even banned from the platform we are creating a connection to. Though, from my experience, as long as you do not start abusing your account-personally, I experienced a rate limit from Instagram. After that, I just disconnected my personal account from the bridge, and I can still use it. On top of that, the most important bridges for me, like WhatsApp, Discord, Telegram, and Signal, worked without any problems.&lt;&#x2F;li&gt;
&lt;li&gt;As we work here with devices that haven&#x27;t received any software and especially security updates, there is-depending on the device and, of course, common sense-always a risk of getting pwned somehow. Please, please do not use this guide and service as a way to replace your current up-to-date device. I personally do important stuff on my workstation and laptop, as I rarely use my smartphone, do not enjoy using it, and if I have to, then just to get the task done. Besides that, when I do anything on these devices, I try to always follow best practices, and if I have to lower the security at some point to be able to connect and interact from the Blackberry Classic, for example, I reevaluate the risks, the settings, and the service itself.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;current-state-of-bridges&quot;&gt;Current state of bridges&lt;&#x2F;h2&gt;
&lt;p&gt;Maybe worth noting, the bridge I currently use for my Blackberry Classic has been in development for over two decades.&lt;&#x2F;p&gt;
&lt;p&gt;The concept of bridges was really common until almost every current popular messenger made it harder; fewer people kept working on them, and they slowly died.&lt;&#x2F;p&gt;
&lt;p&gt;Somehow, in the last few years, if you get into this topic, you can notice more developers allowing access again.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;utilizing-matrix&quot;&gt;Utilizing Matrix&lt;&#x2F;h3&gt;
&lt;p&gt;While Matrix has the most diversity and maybe, in its current state, the best ecosystem, if you want to dip your toes into this topic, it&#x27;s the coolest start.&lt;&#x2F;p&gt;
&lt;p&gt;Sadly, with Matrix&#x27;s modern approaches and the currently supported ways (which are just the enshittification of developers&#x27; minds), it&#x27;s not possible-at least directly-to connect to the Matrix protocol. Still, it&#x27;s possible, which I will come back to later.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;slidge-im&quot;&gt;slidge.im&lt;&#x2F;h3&gt;
&lt;p&gt;Very similar to Matrix&#x27;s approach but backed by, I think, one developer and some contributors, it&#x27;s an ecosystem of bridges for the XMPP protocol.&lt;&#x2F;p&gt;
&lt;p&gt;I do love the XMPP protocol. While being more than two decades old, it&#x27;s stable and lightweight even for the current age and time. Still, sadly, when I tried to use it in combination with the Slidge WhatsApp bridge, it always reached a point where I would send back to my receivers the messages they had sent me. Maybe it got better. If you are interested in contributing in any form to this project, I don&#x27;t think the maintainer will bite you!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bitlbee&quot;&gt;Bitlbee&lt;&#x2F;h3&gt;
&lt;p&gt;This is the bridge I was teasing the whole time. If you want a history lesson about BitlBee, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;BitlBee&quot;&gt;here you go!&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s an-at least for me-insane project!&lt;&#x2F;p&gt;
&lt;p&gt;I currently have set up a bridge to WhatsApp. I receive native notifications on my device, and it has been, until now, the best state in terms of bridging messages to my Blackberry Classic.&lt;&#x2F;p&gt;
&lt;p&gt;From my personal experience, if WhatsApp works flawlessly together with native notifications, then you can be sure it will work for other services for at least a sustainable time, and if things do break and I can contribute in some way to a solution, I will do that!&lt;&#x2F;p&gt;
&lt;h1 id=&quot;how-i-utilize-my-blackberry-classic-together-with-bridges&quot;&gt;How I utilize my Blackberry Classic together with bridges&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;Texting back and forth with friends and family&lt;&#x2F;li&gt;
&lt;li&gt;Spending countless hours diving into the terminal interface with many things to learn, from bash scripts to finding new and exciting ways of CLI note-taking, I shit you not.&lt;&#x2F;li&gt;
&lt;li&gt;Receiving emails and sending emails&lt;&#x2F;li&gt;
&lt;li&gt;SSH tunneling&lt;&#x2F;li&gt;
&lt;li&gt;Git&lt;&#x2F;li&gt;
&lt;li&gt;Streaming music through my self-hosted streaming service&lt;&#x2F;li&gt;
&lt;li&gt;Reading my RSS feed&lt;&#x2F;li&gt;
&lt;li&gt;Spending countless hours searching for any old valuable information and applications hidden somewhere between archive.org, abandoned forums, and broken download links&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;and much, much more.&lt;&#x2F;p&gt;
&lt;p&gt;I do acknowledge all the new and fancy devices with keyboards slapped on them. Some of them are interesting and cool, but for me at least, from my current standpoint, there are many reasons why I stay away from them.&lt;&#x2F;p&gt;
&lt;p&gt;For me, at least, if I may speak openly, they are clout-chasing, a money grab, and, most importantly, promising-maybe actively, maybe passively-false hopes to their customers. I also acknowledge that everyone, even me, needs money to live.&lt;&#x2F;p&gt;
&lt;p&gt;Though from my point of view, there are countless ways of achieving that, and not everything has to be for the money.&lt;&#x2F;p&gt;
&lt;p&gt;I think cyberspace is one of the few chances where we can have a great time together, help each other out, gain knowledge, and utilize this platform to the fullest.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;how-can-you-contribute&quot;&gt;How can you contribute?&lt;&#x2F;h1&gt;
&lt;p&gt;I would start by getting an overview of people who are interested in this topic in general. As BitlBee is working, from my experience, in a somewhat stable way, I would even go so far as to say that we are not limited to Blackberry but to every device that runs a platform called &lt;code&gt;J2ME&lt;&#x2F;code&gt;. If you own such a device and are interested in testing out a connection to my-or even your own-BitlBee instance, let&#x27;s go!&lt;&#x2F;p&gt;
&lt;p&gt;Everything will, of course, be released under a Free and Open Source license.&lt;&#x2F;p&gt;
&lt;p&gt;I will also provide my own personal instance for anyone from this community for free, with my best efforts to keep everything safe and sound for everyone. If you have concerns, which I can fully understand and respect, I am also going to provide, in the future, a way to make the whole setup as easy and guided as possible. Though these are plans for the future. For now, let&#x27;s see what the general interest in this topic is.&lt;&#x2F;p&gt;
&lt;p&gt;I will also link the blog post of my personal site here if you are interested in more obscure topics that I discover in general.&lt;&#x2F;p&gt;
&lt;p&gt;You may feel free to respond here or through CMail. Otherwise, if you insist on contacting me off-platform, there will be ways. Though we have the whole service and infrastructure here, so let&#x27;s utilize it.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Get the latest NixOS wiki changes via RSS</title>
        <published>2025-11-22T00:00:00+00:00</published>
        <updated>2025-11-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/get-the-latest-nixos-wiki-changes-via-rss/"/>
        <id>/blog/get-the-latest-nixos-wiki-changes-via-rss/</id>
        
        <content type="html" xml:base="/blog/get-the-latest-nixos-wiki-changes-via-rss/">&lt;p&gt;NixOS is sadly known for its &lt;em&gt;bad documentation&lt;&#x2F;em&gt;, though the community is actively working on it.&lt;&#x2F;p&gt;
&lt;p&gt;You can even get the latest changes via RSS.&lt;&#x2F;p&gt;
&lt;p&gt;Just add the following RSS feed to your preferred RSS reader:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;wiki.nixos.org&#x2F;w&#x2F;api.php?hidebots=1&amp;amp;translations=filter&amp;amp;urlversion=1&amp;amp;days=7&amp;amp;limit=50&amp;amp;action=feedrecentchanges&amp;amp;feedformat=atom&quot;&gt;Official NixOS Wiki - Recent changes {en}&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For me personally, it&#x27;s very interesting to see which changes are made, and sometimes I even spot interesting or new options.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Glorious SSH Part 1: Setting up SSH on a Blackberry Classic, how to contribute and a rant</title>
        <published>2025-11-11T00:00:00+00:00</published>
        <updated>2025-11-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/glorious-ssh-part-1-setting-up-ssh-on-a-blackberry-classic-how-to-contribute-and-a-rant/"/>
        <id>/blog/glorious-ssh-part-1-setting-up-ssh-on-a-blackberry-classic-how-to-contribute-and-a-rant/</id>
        
        <content type="html" xml:base="/blog/glorious-ssh-part-1-setting-up-ssh-on-a-blackberry-classic-how-to-contribute-and-a-rant/">&lt;p&gt;&lt;a id=&quot;org561dbc0&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h1&gt;
&lt;p&gt;Now, some may have realized it or not, but I think SSH, besides Git, is one of the greatest inventions mankind could possibly ever experience-no joke.&lt;&#x2F;p&gt;
&lt;p&gt;As much as I love to break my head over obscure topics such as Nix, Rust, and Emacs; whether it&#x27;s possible to somehow use a Blackberry Classic as a semi-daily driver, because I just flippin love the OS and its keyboard (we will get to that).&lt;&#x2F;p&gt;
&lt;p&gt;SSH in general, and especially my &lt;code&gt;ssh_config&lt;&#x2F;code&gt;, is deployed everywhere I need it. All my aliases are the same, and it ALWAYS WORKS.&lt;&#x2F;p&gt;
&lt;p&gt;I can&#x27;t emphasize enough how much the SSH protocol saved my butt.&lt;&#x2F;p&gt;
&lt;p&gt;Now, if you have a basic understanding of SSH, it&#x27;s able to replace a big chunk of your networking stack.&lt;&#x2F;p&gt;
&lt;p&gt;You don&#x27;t believe me? I was the same soydev as you, wanting a &lt;code&gt;docker_compose.yaml&lt;&#x2F;code&gt; for every service, only to realize that I somehow did not save the initial root password, now needing to log in to the Control Panel of my VPS provider to reset it.&lt;&#x2F;p&gt;
&lt;p&gt;SSH made me that Gigachad who just &lt;code&gt;ssh-copy-id target@example.com&lt;&#x2F;code&gt;, and he is good to go. Never do I have to care about the password or even dare to reset it through the VPS Control Panel of my hosting provider.&lt;&#x2F;p&gt;
&lt;p&gt;And exactly for that reason I want to showcase the great power of GLORIOUS SSH, its possibilities, and explore SSH packages and scripts I was not even aware of until this point!&lt;&#x2F;p&gt;
&lt;p&gt;Now, let&#x27;s get started&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org66d1f61&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a id=&quot;org78cac8a&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;blackberry-os-10&quot;&gt;Blackberry OS 10&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;m not going to go too deep into listing the devices that support BBOS 10.&lt;&#x2F;p&gt;
&lt;p&gt;For the German folks, you can grab a used device &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kleinanzeigen.de&#x2F;s-blackberry&#x2F;k0&quot;&gt;here&lt;&#x2F;a&gt; for 30-60 Eur. The investment is really worth it and fun.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;orgccf1e0e&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;berrycore&quot;&gt;BerryCore&lt;&#x2F;h2&gt;
&lt;p&gt;You may grab BerryCore &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sw7ft&#x2F;BerryCore&quot;&gt;from here&lt;&#x2F;a&gt; and follow the installation. It&#x27;s well documented, and sw7ft is just a great guy. I truly believe his contribution is not recognized enough.&lt;&#x2F;p&gt;
&lt;p&gt;If you do not know him, let me explain his work. He sits there for hours, trying to provide the most diverse utilities from core POSIX-COMPLIANT CLI and TUI tools, packaging until he reached a point where he could run a Linux VM inside these more than 10-year-obsolete devices, getting X11 and even GCC 9 to run.&lt;&#x2F;p&gt;
&lt;p&gt;Now, if you also contributed in any way to BerryCore and I did not realize it, please let me know! I would love to mention your work too, because the possibilities really got to a point where even I got interested in the project again.&lt;&#x2F;p&gt;
&lt;p&gt;Sadly, besides the installation, the documentation of the whole project is a lot of AI slop; many packages are not documented, while there are some real gold gems buried inside this project.&lt;&#x2F;p&gt;
&lt;p&gt;I will demonstrate one, which I did just for fun, while being sure it would never work.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s the great thing about free and open-source software. We may fork the whole project if things do not go as we like, but we can also contribute to the project so we as a community as a whole can benefit and grow.&lt;&#x2F;p&gt;
&lt;p&gt;Contributing to documentation for a project in such a state is really essential.&lt;&#x2F;p&gt;
&lt;p&gt;Even I, who literally spends his whole time in this area, had to wrap my head many times to find the right information.&lt;&#x2F;p&gt;
&lt;p&gt;Another important point to mention is that you don&#x27;t need to be tech-savvy at all to contribute to docs.&lt;&#x2F;p&gt;
&lt;p&gt;Open any text editor, &lt;em&gt;I use Emacs, the world&#x27;s greatest Emacs Lisp interpreter btw&lt;&#x2F;em&gt;, start your research, and note down everything that could be useful.&lt;&#x2F;p&gt;
&lt;p&gt;Most of the time these notes are just links to posts, repos, or configurations that worked for me.&lt;&#x2F;p&gt;
&lt;p&gt;The whole writing is done at the end.&lt;&#x2F;p&gt;
&lt;p&gt;At the current state, it does not matter that much how you write the documentation, as long as everything is somewhat logical, easy to reproduce, and actually works lmao.&lt;&#x2F;p&gt;
&lt;p&gt;Now, enough of the chit-chat; let&#x27;s start truly reviving these devices.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org8211d5b&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ssh-setup&quot;&gt;SSH Setup&lt;&#x2F;h2&gt;
&lt;p&gt;It took me hours just to be able to connect from my host to my Blackberry Classic because of three issues:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;I could not figure out the user I needed to specify for the connection&lt;&#x2F;li&gt;
&lt;li&gt;I had problems with key negotiation, as Blackberry OS 10 devices use an older OpenSSH version&lt;&#x2F;li&gt;
&lt;li&gt;I did not know how to set up the SSH daemon on my Blackberry device the right way&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Now here are the solutions:&lt;&#x2F;p&gt;
&lt;p&gt;How to set up the SSH daemon is even written in an older Blackberry project by sw7ft himself. He may have forgotten it while being busy achieving value for humankind.&lt;&#x2F;p&gt;
&lt;p&gt;[[&amp;lt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;BerryFarm&#x2F;berrymuch&#x2F;blob&#x2F;master&#x2F;doc&#x2F;HOWTO-start-ssh-server.md&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;BerryFarm&#x2F;berrymuch&#x2F;blob&#x2F;master&#x2F;doc&#x2F;HOWTO-start-ssh-server.md&lt;&#x2F;a&gt;&amp;gt;][[&amp;lt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;BerryFarm&#x2F;berrymuch&#x2F;blob&#x2F;master&#x2F;doc&#x2F;HOWTO-start-ssh-server.md&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;BerryFarm&#x2F;berrymuch&#x2F;blob&#x2F;master&#x2F;doc&#x2F;HOWTO-start-ssh-server.md&lt;&#x2F;a&gt;&amp;gt;]][source]]&lt;&#x2F;p&gt;
&lt;p&gt;We will utilize his second approach, as it&#x27;s foolproof, worked out of the box, and the first one did not work for me. So why not let him talk?:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;first run&lt;&#x2F;p&gt;
&lt;p&gt;sshd -Dd&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;then do it again after it generates the private RSA key&lt;&#x2F;p&gt;
&lt;p&gt;sshd -Dd&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;generate a RSA 2048 key. on your client,(the device your are planning to ssh from (note i have troulbe using a mac M1 laptop, they key doesn&#x27;t work so i am using a linux VM&lt;&#x2F;p&gt;
&lt;p&gt;ssh-keygen -t rsa -b 2048 -C &quot;your&lt;sub&gt;email&lt;&#x2F;sub&gt;@example.com&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Copy that key and inside your blackberry, when you first start term49 (term48)&lt;&#x2F;p&gt;
&lt;p&gt;vi .ssh&#x2F;authorized&lt;sub&gt;keys&lt;&#x2F;sub&gt;&lt;&#x2F;p&gt;
&lt;p&gt;now paste the generated key into that file.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;start the sshd server( i close the app and reopen it before running this&lt;&#x2F;p&gt;
&lt;p&gt;sshd -Dd&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;done&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;one problem solved, two are left&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org18e6d42&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;getting-the-ssh-user&quot;&gt;Getting the SSH User&lt;&#x2F;h2&gt;
&lt;p&gt;TLDR: It&#x27;s &lt;code&gt;App&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So if you want to SSH to your Blackberry, type in your terminal or SSH program:&lt;&#x2F;p&gt;
&lt;p&gt;ssh App@target.ip:2022&lt;&#x2F;p&gt;
&lt;p&gt;I was able to find the answer also in an almost one-year-old video from sw7ft, where his SSH program displays the username and even the port. Nice!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;orgbdbd542&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;id-rsa-could-or-could-not-be-deprecated&quot;&gt;&lt;code&gt;id-rsa&lt;&#x2F;code&gt; could or could not be deprecated&lt;&#x2F;h2&gt;
&lt;p&gt;If you were able to SSH from the second solution into your device, then you did it!&lt;&#x2F;p&gt;
&lt;p&gt;Sadly, it was, of course, not over for me.&lt;&#x2F;p&gt;
&lt;p&gt;As I previously mentioned the issue, here are two solutions:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;for the sane people just utilizing a &lt;code&gt;ssh_config&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Add the following snippet on your host machine into the &lt;code&gt;.ssh&#x2F;config&lt;&#x2F;code&gt;. You may change the &lt;code&gt;blackberry&lt;&#x2F;code&gt; in the first line to whatever name you like! For the sake of the demonstration, I will keep it as is, and take care to adjust the &lt;em&gt;CHANGE&lt;sub&gt;ME&lt;&#x2F;sub&gt;&lt;&#x2F;em&gt; to your path and host. I will keep the port on 2022, as it&#x27;s preconfigured already on the Blackberry devices. If you changed it, then of course adjust it:&lt;&#x2F;p&gt;
&lt;p&gt;Host blackberry Port 2022 IdentitiesOnly yes User App HostName CHANGE&lt;sub&gt;ME&lt;&#x2F;sub&gt; IdentityFile &lt;em&gt;home&#x2F;CHANGE&lt;sub&gt;ME&lt;&#x2F;sub&gt;&lt;&#x2F;em&gt;.ssh&#x2F;CHANGE&lt;sub&gt;ME&lt;&#x2F;sub&gt; HostKeyAlgorithms +ssh-rsa PubkeyAcceptedKeyTypes +ssh-rsa&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;now for the not-so-sane people like me who configure their SSH settings via NixOS or home-manager:&lt;&#x2F;p&gt;
&lt;p&gt;{ programs.ssh = { enable = true; enableDefaultConfig = false; matchBlocks = { &quot;blackberry&quot; = { hostname = &quot;192.168.8.223&quot;; port = 2022; identityFile = &quot;&lt;em&gt;home&#x2F;cashmere&lt;&#x2F;em&gt;.ssh&#x2F;bb&quot;; identitiesOnly = true; user = &quot;App&quot;; extraOptions = { HostKeyAlgorithms = &quot;+ssh-rsa&quot;; PubkeyAcceptedKeyTypes = &quot;+ssh-rsa&quot;; }; }; &quot;*&quot; = { extraOptions = { StrictHostKeyChecking = &quot;ask&quot;; VerifyHostKeyDNS = &quot;yes&quot;; VisualHostKey = &quot;yes&quot;; }; }; }; }; }&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;And that&#x27;s all!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org48c8386&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ssh-into-your-device&quot;&gt;SSH into your device&lt;&#x2F;h2&gt;
&lt;p&gt;Now, if everything went well, you may SSH into your device with the following command:&lt;&#x2F;p&gt;
&lt;p&gt;ssh blackberry&lt;&#x2F;p&gt;
&lt;p&gt;Now we have full user access on the Blackberry through GLORIOUS SSH.&lt;&#x2F;p&gt;
&lt;p&gt;If it&#x27;s nothing for you because you insist on full root access, then this guide was not for you, sorry :(.&lt;&#x2F;p&gt;
&lt;p&gt;If you appreciate this guide or are interested in the possibilities, let me just count a few that come to mind right now:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Using yours as a portable SSH device to access from and into&lt;&#x2F;li&gt;
&lt;li&gt;Syncing media from and to your Blackberry through &lt;code&gt;rsync&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Port forwarding through SSH, which makes it possible to expose your great device not only locally but even to the whole world, to demonstrate how eager you are to host your static site on an obsolete device&lt;&#x2F;li&gt;
&lt;li&gt;Ricing vim&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a id=&quot;org980f77a&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;let-s-rice-vim&quot;&gt;Let&#x27;s rice vim&lt;&#x2F;h1&gt;
&lt;p&gt;Yeah, no joke, it somehow worked.&lt;&#x2F;p&gt;
&lt;p&gt;As I was utilizing vim and its great motions even on a Blackberry device, which is just superior, I realized we have access to vim version 8.x.&lt;&#x2F;p&gt;
&lt;p&gt;I checked out, out of fun, what vim version was required to set up a package manager,&lt;&#x2F;p&gt;
&lt;p&gt;\#+BEGIN&lt;sub&gt;COMMENT&lt;&#x2F;sub&gt; Yes great vim people, I never was able to fully experience the sanity of VimScript as I just started out with neovim and lua, before fully converting to the church of Emacs.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;I still use evil-mode in Emacs.&lt;&#x2F;em&gt; \#+BEGIN&lt;sub&gt;COMMENT&lt;&#x2F;sub&gt;&lt;&#x2F;p&gt;
&lt;p&gt;only to read vim had native support for external packages&#x2F;plugins from version 8.x and higher.&lt;&#x2F;p&gt;
&lt;p&gt;After a small research I found &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;preservim&#x2F;nerdtree&quot;&gt;Nerdtree&lt;&#x2F;a&gt;, which allows us to integrate a file explorer into vim on a Blackberry, which is, as I mentioned many times, obsolete, not supported anymore, and not having a really native vim package in the first place.&lt;&#x2F;p&gt;
&lt;p&gt;In theory, we could set up pyright, a so-called LSP that allows us to have various checks of our beloved Python scripts. If some guy is able to get vim, gcc, and a somewhat current version of Python with external library support running, some of us-somebody-could set it up, or not. Many things are untold if nobody is going to discover them and note them down for the community.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;orgde0ca3b&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;rant&quot;&gt;Rant&lt;&#x2F;h1&gt;
&lt;p&gt;Now, this is going to be a lengthy rant about how I experienced a negative shift in the BlackBerry community here on Reddit.&lt;&#x2F;p&gt;
&lt;p&gt;If you have read this far but are not into drama, I’d keep having fun with GLORIOUS SSH, as it’s something you will benefit from.&lt;&#x2F;p&gt;
&lt;p&gt;If you care about values in general, in various forms, I’d keep reading.&lt;&#x2F;p&gt;
&lt;p&gt;I’m not too deep into the BlackBerry topic, but long enough that I saw myself too much, sadly.&lt;&#x2F;p&gt;
&lt;p&gt;And yes, I am going to call out some people, because it’s sad to see the point we’ve arrived at compared to where I started.&lt;&#x2F;p&gt;
&lt;p&gt;New implementations like the Hackberry Pi and similar projects, which recycle obsolete BlackBerry 10 devices to create something new, are great! I have nothing to add to that.&lt;&#x2F;p&gt;
&lt;p&gt;Projects like BerryMuch and term49 are absolutely insane to me. This is going to be our core utility for this part.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sw7ft&quot;&gt;sw7ft&lt;&#x2F;a&gt;, a very great and kind developer, is releasing such insane updates; people just have to take his core contribution and start building things on top of it.&lt;&#x2F;p&gt;
&lt;p&gt;Same goes for the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;t.me&#x2F;berryfarm_org&quot;&gt;Berryfarm group&lt;&#x2F;a&gt;. It’s just a small group of BlackBerry enthusiasts who share their knowledge with others. Great!&lt;&#x2F;p&gt;
&lt;p&gt;Then there are people like &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;@ReturningRetro&quot;&gt;ReturningRetro&lt;&#x2F;a&gt;, who started with great intentions but somehow lost track.&lt;&#x2F;p&gt;
&lt;p&gt;Same goes for CrackBerry Kevin. I don’t know him personally, and I’m pretty sure his contribution to BlackBerry itself will forever outweigh what I could ever contribute. Still, from what I saw in the last several months, I see nothing but profit made off people having false hope of reviving BlackBerry devices to a state that is unlikely to be reached again. Sorry to say it, but that’s the current state, at least for me.&lt;&#x2F;p&gt;
&lt;p&gt;Even a Zinwa Q25, as much as it’s a BlackBerry, I don’t know how much this project has to do with BlackBerry.&lt;&#x2F;p&gt;
&lt;p&gt;The folks over on [&#x2F;r&#x2F;cyberdeck](&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;cyberdeck&quot;&gt;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;cyberdeck&lt;&#x2F;a&gt;** are slapping a keyboard onto anything that comes to mind; still, they rarely come over here to present their newest builds, let alone try to monetize them.&lt;&#x2F;p&gt;
&lt;p&gt;I follow them too, and what I’ve gathered so far is that they’re just some chill people who like devices with a keyboard attached to them.&lt;&#x2F;p&gt;
&lt;p&gt;Still, that doesn’t mean hope is lost. We, as a community-and especially the tech-savvy people-can contribute more than enough resources to make these devices somewhat workable for us and for the non-tech-savvy people.&lt;&#x2F;p&gt;
&lt;p&gt;All I’m currently seeing is people wrapping some JavaScript into a webview, trying to get WhatsApp working in very obscure ways, and some people are literally charging money for these laggy services and applications while saying the performance issues are due to the old hardware.&lt;&#x2F;p&gt;
&lt;p&gt;Now, could somebody explain to me why 10-year-old APKs are still running much better than these freshly developed applications? Like, really, I want to be proven wrong, just so I can learn from the current state.&lt;&#x2F;p&gt;
&lt;p&gt;Now, don’t get me wrong. I think it’s always nice to earn money while providing value and doing something you like.&lt;&#x2F;p&gt;
&lt;p&gt;But the whole situation has come to a point where everything is just getting weird, and the whole essence of why I enjoyed being here has been lost.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;orgcbb862b&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;where-to-roast-me&quot;&gt;Where to roast me?&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;em&gt;Edit:&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Of course, in the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;blackberry&#x2F;comments&#x2F;1ou2dpq&#x2F;a_rant_about_the_current_blackberry_situation&#x2F;&quot;&gt;Reddit post&lt;&#x2F;a&gt;, which I will link as soon as this post is online.&lt;&#x2F;p&gt;
&lt;p&gt;You may roast me through &lt;a href=&quot;mailto:cashmere@cashmere.rs&quot;&gt;mail&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Otherwise, I am semi-active on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;matrix.to&#x2F;#&#x2F;@cashmere:cashmere.rs&quot;&gt;Matrix&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If you find any other profiles on other platforms, it depends on whether I see it or not.&lt;&#x2F;p&gt;
&lt;p&gt;I think this rant may trigger more people than I expect. If so, and I get downvoted, then at least I can tell myself that I tried.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Create your own music service</title>
        <published>2025-11-09T00:00:00+00:00</published>
        <updated>2025-11-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/create-your-own-music-service/"/>
        <id>/blog/create-your-own-music-service/</id>
        
        <content type="html" xml:base="/blog/create-your-own-music-service/">&lt;p&gt;&lt;a id=&quot;org5b4a0f9&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h1&gt;
&lt;p&gt;Through the rise of Spotify, we lost our connection to one of the most important media: audio.&lt;&#x2F;p&gt;
&lt;p&gt;While we get access to the entire music library of the whole world, we still tend to listen to the same or similar artists, playlists, and maybe even genres.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;orge0a0e6f&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h1&gt;
&lt;p&gt;If you take a look into the world of self-hosting a music streaming service, there is &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;basings&#x2F;selfhosted-music-overview&quot;&gt;a good collection to choose from&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I, for myself, chose for the following reasons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Easy to set up&lt;&#x2F;li&gt;
&lt;li&gt;Easy to configure&lt;&#x2F;li&gt;
&lt;li&gt;Compatible with the&lt;&#x2F;li&gt;
&lt;li&gt;Able to report your listens to&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;As my music player, I chose for the following reasons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Modern and familiar UI&lt;&#x2F;li&gt;
&lt;li&gt;Compatible with and&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;To collect stats and get new recommendations about my listening, I am using for the following reasons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Detailed music stats&lt;&#x2F;li&gt;
&lt;li&gt;New recommendations every week based on my previous music behavior&lt;&#x2F;li&gt;
&lt;li&gt;Compatible with many music streaming providers, so you are not limited to self-host your own music to get more information about your music behavior&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;a id=&quot;orgc9e2af5&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;subsonic-api&quot;&gt;Subsonic API&lt;&#x2F;h1&gt;
&lt;p&gt;The Subsonic API is an open REST interface that was developed over 15 years ago and has established itself as the de facto standard for self-hosted music streaming. Although the original Subsonic server is no longer actively developed, modern servers like Navidrome continue to use the API because it provides instant compatibility with a huge ecosystem of client apps for all platforms. Thanks to this standardization, developers don&#x27;t have to rewrite their apps for every single server.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;orgb2494a7&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;navidrome&quot;&gt;Navidrome&lt;&#x2F;h1&gt;
&lt;p&gt;You can find the instructions on how to set up Navidrome &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.navidrome.org&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;For myself, I use the Nix ecosystem to set up Navidrome, as it has its own &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;search.nixos.org&#x2F;options?channel=unstable&amp;amp;query=navidrome&quot;&gt;service&lt;&#x2F;a&gt;. This is the snippet to set it up if you run &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;nixos.org&quot;&gt;NixOS&lt;&#x2F;a&gt; too:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;nix&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #EA999C;font-style: italic;&quot;&gt;	lib&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt;	...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;}:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;	services&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;navidrome&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;	enable&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E78284;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;	settings&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;font-style: italic;&quot;&gt;		# Allowing navidrome to collect anonymized data on how you use navidrome. I personally turned it on as I really like navidrome and I want to contribute somehow to its development. If you do not want it, then you may just turn it off&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;font-style: italic;&quot;&gt;		# You can read more about it here:https:&#x2F;&#x2F;www.navidrome.org&#x2F;docs&#x2F;getting-started&#x2F;insights&#x2F; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;		EnableInsightsCollector&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E78284;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;font-style: italic;&quot;&gt;		# the path where you store all your music for example &#x2F;mnt&#x2F;music&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;		MusicFolder&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt; &amp;quot;&#x2F;path&#x2F;to&#x2F;your&#x2F;music&#x2F;folder&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;font-style: italic;&quot;&gt;		# The address which you want to use. As I use caddy to reverse proxy the domain to the address I will leave it on localhost. Otherwise if you do not own a domain, then change the address to: &amp;quot;0.0.0.0&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;		Address&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt; &amp;quot;127.0.0.1&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;		Port&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EF9F76;&quot;&gt; 4533&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;		EnableSharing&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E78284;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;font-style: italic;&quot;&gt;		# link your base url of the reverse proxy if you own a domain otherwise remove it.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;		BaseUrl&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt; &amp;quot;https:&#x2F;&#x2F;navidrome.example.com&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;	};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;	};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;font-style: italic;&quot;&gt;	# If you use caddy as a reverse proxy then you can setup the reverse proxy like that. Otherwise adjust it to nginx or other service which you use.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;	services&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;caddy&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;virtualHosts&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;	&amp;quot;navidrome.example.com&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;		extraConfig&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt; &amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;		reverse_proxy localhost:4533&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;		&amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;	};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;	};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Once Navidrome is online, you can connect it. If your Navidrome instance is public, then connect to it quickly, as you need to set up the admin account. You can read more about it &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.navidrome.org&#x2F;docs&#x2F;getting-started&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Once that&#x27;s done, Navidrome will start indexing your music folder.&lt;&#x2F;p&gt;
&lt;p&gt;As I like to separate administration accounts from my own personal accounts, you may create a new account and limit the access according to your needs.&lt;&#x2F;p&gt;
&lt;p&gt;Navidrome allows you to stream your music directly through the web interface. If it&#x27;s enough for you and you don&#x27;t need another client and stats, then you are good to go from here!&lt;&#x2F;p&gt;
&lt;p&gt;Otherwise, if you want more control, then keep on reading :).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org0cf391a&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;feishin&quot;&gt;Feishin&lt;&#x2F;h1&gt;
&lt;p&gt;You can read more about Feishin &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jeffvli&#x2F;feishin&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Like Navidrome, the Nix ecosystem also offers a native package for Feishin.&lt;&#x2F;p&gt;
&lt;p&gt;You can add it to your system like this:&lt;&#x2F;p&gt;
&lt;p&gt;NixOS:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;nix&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #EA999C;font-style: italic;&quot;&gt;	pkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt;	...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;}:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;	environment&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;systemPackages&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt; with&lt;&#x2F;span&gt;&lt;span&gt; pkgs;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	feishin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;	];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Home Manager:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;nix&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #EA999C;font-style: italic;&quot;&gt;	pkgs&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt;	...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;}:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;	home&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;packages&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #CA9EE6;&quot;&gt; with&lt;&#x2F;span&gt;&lt;span&gt; pkgs;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	feishin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;	];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Once Feishin is installed, start it, select Navidrome, and enter the URL and credentials of your Navidrome instance. Now you can start listening to your music collection, create playlists, and so on! :).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org0beee20&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;listenbrainz&quot;&gt;Listenbrainz&lt;&#x2F;h1&gt;
&lt;p&gt;To connect Listenbrainz with your Navidrome instance, you need to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;musicbrainz.org&#x2F;register&quot;&gt;create an account&lt;&#x2F;a&gt; on Musicbrainz first. Then just follow the few &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.navidrome.org&#x2F;docs&#x2F;usage&#x2F;scrobbling&#x2F;#listenbrainz&quot;&gt;steps&lt;&#x2F;a&gt; according to the Navidrome documentation.&lt;&#x2F;p&gt;
&lt;p&gt;Now you can start listening to your music collection from any client. You do not need to listen to your music from the Navidrome web client. As long as you are connected to the account where the Listenbrainz API is connected, Navidrome will report your current listens to Listenbrainz.&lt;&#x2F;p&gt;
&lt;p&gt;You may now stalk &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;listenbrainz.org&#x2F;user&#x2F;cashmeresocial&#x2F;&quot;&gt;me&lt;&#x2F;a&gt; whenever I listen to new music!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;org5b94f32&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;cool-things-i-spotted-with-this-setup&quot;&gt;Cool things I spotted with this setup&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a id=&quot;org7b7e102&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;offline-usage&quot;&gt;Offline Usage&lt;&#x2F;h2&gt;
&lt;p&gt;Of course, you can listen to your own music offline!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a id=&quot;orgc5b0b3b&quot;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;share-your-playlist-with-family-friends&quot;&gt;Share your playlist with family &amp;amp; friends&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s say you created the perfect playlist of all time, and you want to share it with your best friend.&lt;&#x2F;p&gt;
&lt;p&gt;Navidrome allows listening to playlists, even without an account.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>My new services are online!</title>
        <published>2025-10-22T00:00:00+00:00</published>
        <updated>2025-10-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/my-new-services-are-online/"/>
        <id>/blog/my-new-services-are-online/</id>
        
        <content type="html" xml:base="/blog/my-new-services-are-online/">&lt;h1 id=&quot;wiki&quot;&gt;Wiki&lt;&#x2F;h1&gt;
&lt;p&gt;You may find my new wiki &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cashmere.rs&#x2F;wiki&#x2F;&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;gallery&quot;&gt;Gallery&lt;&#x2F;h1&gt;
&lt;p&gt;I finally had the time to find a minimal gallery where I can dump galleries. I found lychee. It&#x27;s great and enough to share a gallery with somebody.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-is-the-current-state-of-these-services&quot;&gt;What is the current state of these services?&lt;&#x2F;h1&gt;
&lt;p&gt;Both are work in progress. Never the less i want to release them to have some kind of pressure to continue maintaining them.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Passkeys Are Short Lived</title>
        <published>2025-09-04T00:00:00+00:00</published>
        <updated>2025-09-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/passkeys-are-short-lived/"/>
        <id>/blog/passkeys-are-short-lived/</id>
        
        <content type="html" xml:base="/blog/passkeys-are-short-lived/">&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h1&gt;
&lt;p&gt;I was very happy when I discovered that Vaultwarden had implemented passkey integration.&lt;&#x2F;p&gt;
&lt;p&gt;Sadly, I later realized how locked down this feature is.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-are-passkeys&quot;&gt;What are passkeys?&lt;&#x2F;h1&gt;
&lt;p&gt;Passkeys are a mechanism (or login format) that lets you log in to certain sites by verifying legitimacy through your own passkey.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;advantages&quot;&gt;Advantages&lt;&#x2F;h1&gt;
&lt;p&gt;The advantages are that you have high security during the login phase. It also cuts out phishing schemes, as during the login phase, the key is valid for only one login. It might be possible to do some kind of MITM attack, but I am not sure what the capabilities would be to sniff the traffic and use it to your advantage.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;disadvantages&quot;&gt;Disadvantages&lt;&#x2F;h1&gt;
&lt;p&gt;Now here comes the worst part about passkeys. While they are really convenient to use and many popular operating systems and password managers have already implemented passkeys, they are not easy to export, unlike TOTP.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;totp-vs-passkeys&quot;&gt;TOTP vs Passkeys&lt;&#x2F;h1&gt;
&lt;p&gt;TOTP lets you export the private key and import it into another app very easily. With some tricks, it is even possible to export your TOTPs from the Google Authenticator app, as it is not possible out of the box, but it is possible.&lt;&#x2F;p&gt;
&lt;p&gt;Sadly, it is not possible to do the same with passkeys. While the convenience is excellent, if you are like me and like to test different applications and services, it is a must that you can control data as flexibly as a simple text file.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;the-walled-garden&quot;&gt;The walled garden&lt;&#x2F;h1&gt;
&lt;p&gt;I have been using FLOSS password managers for several years now. I started out with KeePassXC and then later switched to my own self-hosted Bitwarden via Vaultwarden.&lt;&#x2F;p&gt;
&lt;p&gt;Importing and exporting all my required data was easy, including TOTP.&lt;&#x2F;p&gt;
&lt;p&gt;Some months ago, I started to set up some passkeys for common sites that also support them.&lt;&#x2F;p&gt;
&lt;p&gt;The integration was also pretty easy.&lt;&#x2F;p&gt;
&lt;p&gt;Though I am really happy with Vaultwarden, I really like and enjoy the concept of managing things through Git and some other third-party software. That is the reason why I started using &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;passwordstore.org&quot;&gt;https:&#x2F;&#x2F;passwordstore.org&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;As I already use Git to manage all my org files, pass fits neatly into my workflow.&lt;&#x2F;p&gt;
&lt;p&gt;Once I exported my data out of Bitwarden, I realized that:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;There is no way to export the passkeys.&lt;&#x2F;li&gt;
&lt;li&gt;There is no passkey implementation for pass.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h1&gt;
&lt;p&gt;While I really enjoy the concept and still use the passkey function to log in to certain websites, I&#x27;ll stick with TOTP, as its support and implementation are much more mature than passkeys.&lt;&#x2F;p&gt;
&lt;p&gt;If you are interested in reading more about this topic, I highly suggest the following post:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.smokingonabike.com&#x2F;2025&#x2F;01&#x2F;04&#x2F;passkey-marketing-is-lying-to-you&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.smokingonabike.com&#x2F;2025&#x2F;01&#x2F;04&#x2F;passkey-marketing-is-lying-to-you&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>What Emacs, Org Mode, and an old Blackberry taught me as a Gen Z</title>
        <published>2025-08-09T00:00:00+00:00</published>
        <updated>2025-08-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/what-emacs-org-mode-and-an-old-blackberry-taught-me-as-a-gen-z/"/>
        <id>/blog/what-emacs-org-mode-and-an-old-blackberry-taught-me-as-a-gen-z/</id>
        
        <content type="html" xml:base="/blog/what-emacs-org-mode-and-an-old-blackberry-taught-me-as-a-gen-z/">&lt;h1 id=&quot;how-did-i-get-started-with-emacs&quot;&gt;How did I get started with Emacs?&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;overwhelmed-during-my-internship&quot;&gt;Overwhelmed during my internship&lt;&#x2F;h2&gt;
&lt;p&gt;I was at the beginning of my internship at the start of the year. At that time, I was very stressed and overwhelmed for many different reasons. But then one day, I missed a very important appointment. As strange as it sounds, I was really devastated because I knew that with a little more organization in my life, I could have avoided this situation. Then I remembered that many people swear by Emacs &quot;Org Mode&quot; for personal management.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;started-right-away-with-org-mode&quot;&gt;Started right away with Org Mode&lt;&#x2F;h2&gt;
&lt;p&gt;To get started, I checked out the Emacs playlist from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;playlist?list=PL5--8gKSku15uYCnmxWPO17Dq6hVabAB4&quot;&gt;DistroTube&lt;&#x2F;a&gt; to get started, focusing on his &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;Ea_-TaEGa7Y?si=qHg4mImRRKAKR2my&quot;&gt;Org Mode video&lt;&#x2F;a&gt;. It was really the first time I truly understood note taking. Before Org Mode, I had tried countless programs and tools, and it was always the same thing. After setting it up and customizing it with all the tools and plugins, I didn&#x27;t know how to proceed. How should I write a note? Should I use folders? Which plugin should I use when?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Caveat:&lt;&#x2F;em&gt; While using Emacs, I interpreted Emacs philosophy and approach as follows: Emacs is a very powerful tool that can be used to do many different things. Yes, you can use it for many things. Some say Emacs is an operating system, others say Emacs is so powerful that the only thing it lacks is a good text editor. But I can say that if you really commit some time to Emacs, it&#x27;s the last tool that will ever get in your way. I&#x27;ve also learned a lot of new things through the Emacs community. Lots of new and really effective approaches to PMS, lots of different blog posts where people share their experiences on various topics related to Emacs, and much more. I also find the Emacs community to be very thoughtful and super friendly. I really enjoy being here and reading all the different posts.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;org-mode-is-a-walled-garden-and-i-love-it&quot;&gt;Org Mode is a walled garden. And I love it&lt;&#x2F;h2&gt;
&lt;p&gt;Org Mode is really powerful, I think you have to have used it to understand how powerful it is. Unfortunately, support outside of Emacs is very limited. I have tried many different approaches to further edit my Org Notes, but the tools and apps that exist did not appeal to me and, above all, they do not support legacy devices.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;utilizing-everything-is-just-a-simple-text-file&quot;&gt;Utilizing &quot;everything is just a simple text file&quot;&lt;&#x2F;h3&gt;
&lt;p&gt;A few months ago, I bought a Blackberry Classic with the intention of using it as a kind of &quot;PDA&quot; because I like typing on a keyboard. The devices hardly support any Android apps anymore, there are hardly any native apps left, and many modern websites don&#x27;t even load due to JavaScript bloat. But what works surprisingly well are simple HTML files, and there is still a version of Conversations (XMPP) that works, even with notifications. So I took to heart the philosophy I learned from Emacs and Org Mode to utilize the advantages of protocols that have been proven over decades.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;current-state-on-org-web&quot;&gt;Current state on org-web&lt;&#x2F;h3&gt;
&lt;p&gt;I am aware that there is already a project called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;org-web.org&quot;&gt;org-web&lt;&#x2F;a&gt;. However, it has not been actively developed for years. If anyone has a better name, feel free to suggest it to me :).&lt;&#x2F;p&gt;
&lt;p&gt;The following features are currently supported.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Get the status of the current agenda at a certain interval via XMPP&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It is possible to enable and disable this feature.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Receive reminders as notifications for schedules.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Inspired by Thunderbird, where you receive a reminder 15 minutes before an appointment in your calendar.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Set an active time when you want to receive notifications&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;e.g. 08:00-22:00&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Call up the current agenda via Org Web&lt;&#x2F;li&gt;
&lt;li&gt;Call up all existing Org files.&lt;&#x2F;li&gt;
&lt;li&gt;Edit and add headings&#x2F;subheadings&lt;&#x2F;li&gt;
&lt;li&gt;First class support for git (automatic pull&#x2F;push)&lt;&#x2F;li&gt;
&lt;li&gt;First class support for denote&lt;&#x2F;li&gt;
&lt;li&gt;Focus on HTML&#x2F;CSS&lt;&#x2F;li&gt;
&lt;li&gt;Authentication system with a token&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Will more features follow?&lt;&#x2F;p&gt;
&lt;p&gt;Yes, definitely. The whole project is very opinionated based on my personal workflow. However, I would like to expand the whole project in the future. For example, the ability to create a wiki or publish Org Notes as a kind of blog post, and much more.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;tips-and-tricks-for-newcomers&quot;&gt;Tips and tricks for newcomers&lt;&#x2F;h2&gt;
&lt;p&gt;In recent days, newcomers have increasingly asked whether they should use Emacs, whether they should use Obsidian instead, whether they should use Emacs with or without vim bindings, or whether Doom Emacs is good for beginners. I can only recommend starting with Emacs and seeing if it&#x27;s right for you. Just like Neovim today, where the community has made it much more than a text editor, the same is true for Emacs. There are many great projects like Doom Emacs, Spacemacs, etc. that are tailored to us newbies. You can use Emacs with or without VIM bindings. It is possible to keep Emacs minimalistic or customize it to the fullest. Anything is possible! The important thing is to try it out. I know Elisp can look very strange at first. Also, not everyone wants to read through pages and pages of documentation. For example, I love consuming video content (with real meaning and substance!). For this, I can recommend &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;@SystemCrafters&#x2F;videos&quot;&gt;Systemcrafters&lt;&#x2F;a&gt;. He covers pretty much every topic and package you can do with Emacs. His videos are very comprehensive and go into great detail. I still enjoy watching his videos to get new inspiration and ideas. If you&#x27;ve gotten started with Emacs and you like tinkering, I can also recommend the user &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;alphapapa&#x2F;&quot;&gt;alphapapa&lt;&#x2F;a&gt;. He has many cool and interesting packages that extend the functionality of Emacs and Org Mode.&lt;&#x2F;p&gt;
&lt;p&gt;I would be very happy to receive any questions or suggestions.&lt;&#x2F;p&gt;
&lt;p&gt;You can contact me via:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;matrix.to&#x2F;#&#x2F;@cashmere:cashmere.rs&quot;&gt;Matrix&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;mailto:cashmere@autistici.org&quot;&gt;Mail&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>upterm | Instant Terminal Sharing</title>
        <published>2025-08-07T00:00:00+00:00</published>
        <updated>2025-08-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/upterm-instant-terminal-sharing/"/>
        <id>/blog/upterm-instant-terminal-sharing/</id>
        
        <content type="html" xml:base="/blog/upterm-instant-terminal-sharing/">&lt;h1 id=&quot;what-is-upterm&quot;&gt;What is upterm?&lt;&#x2F;h1&gt;
&lt;p&gt;upterm is, in my opinion, the coolest way to access your devices via SSH without a complex and annoying setup.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;how-does-it-work&quot;&gt;How does it work?&lt;&#x2F;h1&gt;
&lt;p&gt;It&#x27;s quite simple. You only need upterm on the device you want to access over the internet, without any port forwarding or anything like that.&lt;&#x2F;p&gt;
&lt;p&gt;You can start it with the following command:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;upterm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt; host&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You&#x27;ll then receive a token, which you use as the username when you want to SSH into your device:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;font-style: italic;&quot;&gt;ssh&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt; TOKEN@uptermd.upterm.dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can automatically accept sessions from another device, interactively accept or reject a session, or even allow only specific public keys from your git profiles. It supports services like Github, Gitlab, and even sourcehut. I found this very convenient, as I switched to sourcehut a few months ago, where access to git repositories primarily works with SSH keys.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;that-s-too-insecure-for-me-i-m-not-going-to-let-the-upterm-hoster-find-out-what-cat-pictures-i-m-transferring-from-one-device-to-another&quot;&gt;That&#x27;s too insecure for me. I&#x27;m not going to let the upterm hoster find out what cat pictures I&#x27;m transferring from one device to another &amp;gt;.&amp;lt;&lt;&#x2F;h1&gt;
&lt;p&gt;No problem. Of course, I wouldn&#x27;t be cashmere if I didn&#x27;t have a suitable Nix service configuration ready for you :D&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;nix&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;	services&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;uptermd&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;		enable&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E78284;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;		openFirewall&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #E78284;&quot;&gt; true&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;		listenAddress&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt; &amp;quot;0.0.0.0&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;		port&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #EF9F76;&quot;&gt; 2223&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;	};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;that-s-it&quot;&gt;That&#x27;s it?&lt;&#x2F;h2&gt;
&lt;p&gt;That&#x27;s it! It&#x27;s not for nothing that SSH is one of my favorite protocols, one I&#x27;ve grown to love over time.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;source&quot;&gt;Source?&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;upterm.dev&#x2F;&quot;&gt;Upterm | Instant Terminal Sharing&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Pay for your search results!</title>
        <published>2025-07-26T00:00:00+00:00</published>
        <updated>2025-07-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/pay-for-your-search-results/"/>
        <id>/blog/pay-for-your-search-results/</id>
        
        <content type="html" xml:base="/blog/pay-for-your-search-results/">&lt;p&gt;I know paying for things that are supposed to be free is a very controversial topic. But we shouldn&#x27;t forget: &quot;If you&#x27;re not paying for the product, you are the product.&quot;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;why-bother-with-all-this&quot;&gt;Why bother with all this?&lt;&#x2F;h1&gt;
&lt;p&gt;Ultimately, this is about the privacy of every single user and creating independence on the internet. For anyone who wants to delve deeper into the topic, I highly recommend &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;@techlore&quot;&gt;Techlore&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-are-my-alternatives&quot;&gt;What are my alternatives?&lt;&#x2F;h1&gt;
&lt;h2 id=&quot;free-search-engines&quot;&gt;Free search engines&lt;&#x2F;h2&gt;
&lt;p&gt;On one hand, we have the well-known services like DuckDuckGo, and more recently, Brave Search and Mullvad Leta.&lt;&#x2F;p&gt;
&lt;p&gt;They&#x27;re free and they provide search results. I&#x27;ve tried switching to these search engines time and time again, but unfortunately, the results are barely usable for me. Of all of them, DuckDuckGo was decent, but even with it, I often had to go back to Google. And we all know how drastically Google&#x27;s results have deteriorated over the years.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;meta-search-engines&quot;&gt;Meta search engines&lt;&#x2F;h2&gt;
&lt;p&gt;To put it simply, these are search engines that forward a user&#x27;s search query, collect the results, and then display them. The search itself is done without any user data.&lt;&#x2F;p&gt;
&lt;p&gt;Here you have projects like SearXNG and Whoogle. They work, but I often got very strange or even worse search results than with Google. So I went back to Google again.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;the-solution-kagi&quot;&gt;The solution? Kagi!&lt;&#x2F;h1&gt;
&lt;p&gt;I discovered Kagi and was immediately intrigued by their concept. A short while later, I was in love.&lt;&#x2F;p&gt;
&lt;p&gt;Kagi itself has become much more than just a paid service for a simple search. It&#x27;s more like a collection of different services.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kagi-s-approach-to-search-engines&quot;&gt;Kagi&#x27;s approach to search engines&lt;&#x2F;h2&gt;
&lt;p&gt;Kagi doesn&#x27;t collect user data. Results are not personalized. They have their own ways of indexing pages (I have no idea how they do it, but it works really well). They use artificial intelligence to summarize search results when needed, but also to match the relevance of the content to the search query.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-really-good-translator-with-proofreading&quot;&gt;A really good translator with proofreading&lt;&#x2F;h2&gt;
&lt;p&gt;Similar to my otherwise all-time favorite translator, DeepL, they offer very similar functions. The translations are usable. It also suggests corrections directly during the translation and explains why the translation turned out that way. You can accept the correction if you want, but you don&#x27;t have to.&lt;&#x2F;p&gt;
&lt;p&gt;If you do want the text correction, it&#x27;s available separately in another tab. The corrections are significantly better than when I send my texts to LLMs and bluntly say, &quot;Here, correct this text for me.&quot;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;interface-for-various-llms&quot;&gt;Interface for various LLMs&lt;&#x2F;h2&gt;
&lt;p&gt;Kagi also offers chat interfaces to interact with a wide variety of LLMs. One reason I loved using Perplexity was that you aren&#x27;t limited to just one AI, like with ChatGPT or Claude. They aren&#x27;t the most powerful LLMs in the cheaper plans, but they&#x27;re serviceable. And since the release of DeepSeek, &quot;open source&quot; LLMs have become a genuinely viable alternative, so I&#x27;m happy to use them. Currently, I really enjoy using Qwen3.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-is-this-all-costing-me-right-now&quot;&gt;What is this all costing me right now?&lt;&#x2F;h2&gt;
&lt;p&gt;€10 a month.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h1&gt;
&lt;p&gt;For me, Kagi brings together the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A fresh and interesting approach to finding relevant content &lt;em&gt;THAT ISN&#x27;T FROM GOOGLE!&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Finally, access to a good translator&#x2F;proofreader that can compete with DeepL and is affordable.&lt;&#x2F;li&gt;
&lt;li&gt;Access to LLMs that are more than sufficient for everyday use, which even led me to immediately cancel my, in my opinion, really expensive Perplexity subscription, and before that, ChatGPT.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There was apparently some criticism that Kagi &quot;tracks&quot; users when Google doesn&#x27;t. Here&#x27;s my take on that. The service doesn&#x27;t have a single tracker on its site that my uBlock Origin would otherwise flag, in contrast to DuckDuckGo. I usually only experience something like that in the Indieweb, lmao. The way Kagi presents itself feels very modern, without letting core aspects like data protection and privacy fall by the wayside.&lt;&#x2F;p&gt;
&lt;p&gt;I can also well imagine that many people—myself included—find it super annoying when companies feel the need to cram artificial intelligence into everything. But Kagi is truly one of the few providers that has implemented it very well so far. Also, AI doesn&#x27;t necessarily have to be a negative thing. As mentioned before, I&#x27;ve been using DeepL since 2018. It&#x27;s a fantastic service, and they were already &quot;advertising&quot; with AI long before LLMs were even a topic of conversation. Furthermore, they offer a very good all-rounder for all the services that are important to me outside of coding.&lt;&#x2F;p&gt;
&lt;p&gt;I currently have the €10 subscription and, as I mentioned, was able to cancel my Perplexity subscription. I&#x27;m more than satisfied so far and am really excited to see what else they&#x27;ll release in the future.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to fix screensharing for Niri WM under NixOS</title>
        <published>2025-06-12T00:00:00+00:00</published>
        <updated>2025-06-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/how-to-fix-screensharing-for-niri-wm-under-nixos/"/>
        <id>/blog/how-to-fix-screensharing-for-niri-wm-under-nixos/</id>
        
        <content type="html" xml:base="/blog/how-to-fix-screensharing-for-niri-wm-under-nixos/">&lt;p&gt;&lt;em&gt;Note&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Everything written here is based on MY RESEARCH AND MY ASSUMPTIONS&lt;&#x2F;p&gt;
&lt;h1 id=&quot;problem&quot;&gt;Problem&lt;&#x2F;h1&gt;
&lt;p&gt;The log output shows that xdg-desktop-portal assigns all interfaces to the GTK portal (&quot;Choosing gtk.portal for…&quot;), which means the system doesn&#x27;t recognize a GNOME session. Without correct session detection, xdg-desktop-portal-gnome refuses to start because it requires an active graphical session.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;symptoms&quot;&gt;Symptoms&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;busctl --user call org.freedesktop.portal.Desktop &#x2F;org&#x2F;freedesktop&#x2F;portal&#x2F;desktop org.freedesktop.portal.ScreenCast CreateSession a{sv} 0&lt;&#x2F;code&gt; returns &quot;No such interface&quot;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;systemctl --user status xdg-desktop-portal-gnome.service&lt;&#x2F;code&gt; shows &quot;inactive (dead)&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Only GTK and WLR portals are running, but no GNOME portal&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;solution&quot;&gt;Solution&lt;&#x2F;h1&gt;
&lt;p&gt;If you have any xdg portal configs in your home manager then remove it&lt;&#x2F;p&gt;
&lt;p&gt;Add the following snippet to your configuration.nix:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;xdg.portal = {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  enable = true;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  extraPortals = with pkgs; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    xdg-desktop-portal-gtk&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    xdg-desktop-portal-gnome&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  config = {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    common = {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      default = [ &amp;quot;gtk&amp;quot; ];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    niri = {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      default = [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &amp;quot;gtk&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        &amp;quot;gnome&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &amp;quot;org.freedesktop.impl.portal.ScreenCast&amp;quot; = [ &amp;quot;gnome&amp;quot; ];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      &amp;quot;org.freedesktop.impl.portal.Screenshot&amp;quot; = [ &amp;quot;gnome&amp;quot; ];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  };&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Add session environment variables to help portal detection:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;environment.sessionVariables = {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  XDG_CURRENT_DESKTOP = &amp;quot;niri&amp;quot;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  XDG_SESSION_TYPE = &amp;quot;wayland&amp;quot;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  XDG_SESSION_DESKTOP = &amp;quot;niri&amp;quot;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Optionally add required GNOME packages:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;environment.systemPackages = with pkgs; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  gnome-keyring&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  nautilus&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;];&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Rebuild your system and restart your session:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo nixos-rebuild switch&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h1 id=&quot;verification&quot;&gt;Verification&lt;&#x2F;h1&gt;
&lt;p&gt;After applying the fix, verify that screensharing works:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;systemctl --user status xdg-desktop-portal-gnome.service&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;busctl --user call org.freedesktop.portal.Desktop &#x2F;org&#x2F;freedesktop&#x2F;portal&#x2F;desktop org.freedesktop.portal.ScreenCast CreateSession a{sv} 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo $XDG_CURRENT_DESKTOP&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo $XDG_SESSION_TYPE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h1 id=&quot;why-this-happens&quot;&gt;Why this happens&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;Niri requires xdg-desktop-portal-gnome specifically for screencasting functionality&lt;&#x2F;li&gt;
&lt;li&gt;Without proper session environment variables, the GNOME portal won&#x27;t start&lt;&#x2F;li&gt;
&lt;li&gt;The system falls back to GTK portal which doesn&#x27;t support ScreenCast interface&lt;&#x2F;li&gt;
&lt;li&gt;This became more prominent after xdg-desktop-portal version 1.17 changed how portal implementations are loaded&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;additional-notes&quot;&gt;Additional Notes&lt;&#x2F;h1&gt;
&lt;ul&gt;
&lt;li&gt;Make sure to run Niri as a session (via niri-session or display manager), not in windowed mode&lt;&#x2F;li&gt;
&lt;li&gt;PipeWire must be running and properly configured for screencasting to work&lt;&#x2F;li&gt;
&lt;li&gt;The configuration creates explicit portal assignments for the Niri desktop environment&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Linux unstable is unstable</title>
        <published>2025-06-12T00:00:00+00:00</published>
        <updated>2025-06-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/linux-unstable-is-unstable/"/>
        <id>/blog/linux-unstable-is-unstable/</id>
        
        <content type="html" xml:base="/blog/linux-unstable-is-unstable/">&lt;h1 id=&quot;topic-of-the-day&quot;&gt;Topic of the Day&lt;&#x2F;h1&gt;
&lt;p&gt;For over two years, I have mainly watched Linux-related videos on YouTube. Many creators share mature and well-informed perspectives on using Linux, such as:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Use whatever gets the job done.&lt;&#x2F;li&gt;
&lt;li&gt;Don&#x27;t hesitate to use Linux.&lt;&#x2F;li&gt;
&lt;li&gt;Linux is highly usable today.&lt;&#x2F;li&gt;
&lt;li&gt;If you need Windows or macOS for your work, use them.&lt;&#x2F;li&gt;
&lt;li&gt;If you don&#x27;t require bleeding-edge software, stay on a stable branch.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;the-dark-side-of-linux&quot;&gt;The &quot;Dark Side&quot; of Linux&lt;&#x2F;h1&gt;
&lt;p&gt;The next section discusses Mattscreative, a YouTube creator with good intentions but often misleading and overly biased opinions. At this point in his video, he criticizes distributions like Mint and Ubuntu for not including the latest Nvidia drivers, claiming that any instability is the fault of the distro maintainers. He praises &quot;stable&quot; distros like PikaOS, suggesting they are superior because they communicate with their users through Discord channels.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;not-everyone-needs-bleeding-edge-software&quot;&gt;Not Everyone Needs Bleeding-Edge Software&lt;&#x2F;h1&gt;
&lt;p&gt;This is true. If you want the latest tools, drivers, and applications, Linux provides a path for that. However, for the vast majority of users, this isn&#x27;t necessary. For example, I run three different devices daily: one workstation and an X220, both running NixOS unstable, and a ThinkPad X12 with Fedora and GNOME. I haven&#x27;t gone completely bleeding-edge because I need my devices to be reliable. It&#x27;s also wise to have a fallback device if something breaks. Currently, my X12 is the most stable, and I still do some tinkering on it—just not as much.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;problems-bugs-and-issues-are-often-upstream&quot;&gt;Problems, Bugs, and Issues Are Often Upstream&lt;&#x2F;h2&gt;
&lt;p&gt;When an issue is upstream, there isn&#x27;t much you can do besides being patient or reverting to an older version. Although these bugs are often fixed quickly, if you rely on the affected software, it can be frustrating to repeatedly refresh repositories and try temporary fixes that might not even work for you. When this happens, it&#x27;s usually not the developers&#x27; fault. It&#x27;s fair to criticize distro maintainers if major bugs remain unfixed for months while new issues are accumulating. Otherwise, please be understanding.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;suggesting-unusual-methods-for-running-software-on-linux&quot;&gt;Suggesting Unusual Methods for Running Software on Linux&lt;&#x2F;h2&gt;
&lt;p&gt;Unfortunately, Mattscreative frequently publishes videos on running software on Linux that was never designed for this platform. Technically, it&#x27;s possible to run Photoshop, Affinity Photo, and similar applications, but in practice, these solutions often break during installation or after updates. If you need certain software on Linux, avoid cluttering your main OS with Wine dependencies. Instead, run a Windows VM if your hardware allows—it&#x27;s sufficient for most photo editing tasks. Otherwise, use the software natively with a dual-boot or separate drive.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;i-am-a-masochist&quot;&gt;I Am a Masochist&lt;&#x2F;h2&gt;
&lt;p&gt;I learned all of this the hard way. I broke my setup by chasing bleeding-edge software and dealt with the resulting quirks. Do yourself a favor: make your own decisions, form your own opinions, and don&#x27;t just follow advice from someone else online because it worked for them.&lt;&#x2F;p&gt;
&lt;p&gt;Why do I still run bleeding-edge? Because I&#x27;m a &quot;masochist&quot;—just kidding. I simply enjoy tinkering when time allows; otherwise, I might go weeks without updating anything.&lt;&#x2F;p&gt;
&lt;p&gt;With that said: &lt;em&gt;Happy hacking!&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to setup Seafile with Caddy on NixOS</title>
        <published>2025-05-13T00:00:00+00:00</published>
        <updated>2025-05-13T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/how-to-setup-seafile-with-caddy-on-nixos/"/>
        <id>/blog/how-to-setup-seafile-with-caddy-on-nixos/</id>
        
        <content type="html" xml:base="/blog/how-to-setup-seafile-with-caddy-on-nixos/">&lt;h1 id=&quot;how-to-setup-seafile-with-caddy-on-nixos&quot;&gt;How to setup Seafile with Caddy on NixOS&lt;&#x2F;h1&gt;
&lt;p&gt;This is going to be a more simplified and approachable way on how to set up Seafile with Caddy on NixOS.&lt;&#x2F;p&gt;
&lt;p&gt;In the documentation of Seafile in NixOS, they use nginx as a reverse proxy. But as nginx and caddy are somehow not compatible with each other &lt;em&gt;(I assume because both want to access ports 443 and 80)&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Here is the rewritten configuration for Caddy in NixOS, which is fully compatible and easier to understand:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #C6D0F5; background-color: #303446;&quot;&gt;&lt;code data-lang=&quot;nix&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;&amp;quot;seafile.cashmere.rs&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #8CAAEE;&quot;&gt;	extraConfig&lt;&#x2F;span&gt;&lt;span style=&quot;color: #81C8BE;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt; &amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;	handle_path &#x2F;seafhttp&#x2F;* {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;		uri strip_prefix &#x2F;seafhttp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;		reverse_proxy unix&#x2F;&#x2F;run&#x2F;seafile&#x2F;server.sock {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;			header_up X-Forwarded-For {http.request.remote}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;			transport http {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;			read_timeout 36000s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;			write_timeout 36000s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;			}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;	reverse_proxy unix&#x2F;&#x2F;run&#x2F;seahub&#x2F;gunicorn.sock {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;		header_up Host {http.request.host}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;		transport http {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;			read_timeout 1200s&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;		}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6D189;&quot;&gt;	&amp;#39;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #949CBB;&quot;&gt;}&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Happy Hacking!&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>My setup (2024)</title>
        <published>2025-05-09T00:00:00+00:00</published>
        <updated>2025-05-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/my-setup-2024/"/>
        <id>/blog/my-setup-2024/</id>
        
        <content type="html" xml:base="/blog/my-setup-2024/">&lt;h1 id=&quot;my-setup-2024&quot;&gt;My setup (2024)&lt;&#x2F;h1&gt;
&lt;p&gt;here you can get an overview of my current setup (づ ◕‿◕ )づ&lt;&#x2F;p&gt;
&lt;h2 id=&quot;lenovo-thinkpad-t480s&quot;&gt;lenovo thinkpad t480s&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;cpu: intel i5-8350u&lt;&#x2F;li&gt;
&lt;li&gt;24gb ram&lt;&#x2F;li&gt;
&lt;li&gt;512gb ssd&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;i love this laptop. it weighs 1.3kg (which is really light for a laptop), i can run virtual machines smoothly on it and other programs even in the background.&lt;&#x2F;p&gt;
&lt;p&gt;the keyboard is very comfortable to type on for a long time. i actually use it for everything. watching videos, programming, project planning, occasionally very light image editing. i miss you photoshop (シ. .)シ&lt;&#x2F;p&gt;
&lt;p&gt;i run nixos as my operating system (i use nixos btw) and to synchronize notifications, files and more i use kde connect. a lifesaver.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;pixel-7-with-grapheneos&quot;&gt;pixel 7 with grapheneos&lt;&#x2F;h2&gt;
&lt;p&gt;there&#x27;s not much to say about it. it&#x27;s a smartphone, but to be honest i hardly use it. i have grapheneos for privacy and security and i especially like the profiles, where i can install my own apps for each profile to isolate social media, my banking apps, from other apps. each profile is really independent from the other and they have many other great features. everyone who has a pixel should take a look at it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ipod-classic-4-generation&quot;&gt;ipod classic 4 generation&lt;&#x2F;h2&gt;
&lt;p&gt;i use it to listen to music, who would have thought it ヽ(°〇°)ﾉ. i bought the device in july and it was an adventure. at the beginning i thought i would buy it and gradually i upgraded it. after two weeks the entire hard disk broke hahaha. now i directly changed the old 20gb hard disk to a 128gb sd card, as well as the battery. now the device runs super fast and the battery finally lasts more than 3 hours. did i scratch the device, more than it was already scratched? of course. did i half-scratch the device when i replaced it, had half a heart attack, had software problems only to find a 3 year old solution on reddit that was so weird that it worked, i had a good feeling that it would work and it actually worked in the end and that&#x27;s an overlong sentence but it&#x27;s extra so to represent this unnecessary headache? yes i did. did i see all the problems coming? yes i saw that coming too. then why am i giving myself this headache? because i love it. still, maybe i spent a bit too much on the device and i should have bought the 5th generation instead, but the experience was still great.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kindle-scribe&quot;&gt;kindle scribe&lt;&#x2F;h2&gt;
&lt;p&gt;if i were in a relationship with the kindle scribe, the status would be &quot;it&#x27;s complicated&quot;. i mainly use it for notes. when i tried to jailbreak it right after i bought it, i restarted it as a precaution and lo and behold. it updated automatically. it&#x27;s very integrated into the amazon ecosystem, which i hate. that&#x27;s why it&#x27;s sitting in airplane mode waiting for the next jailbreak. the notes function works and does what it&#x27;s supposed to. it&#x27;s still not comparable to a remarkable. of course it&#x27;s not the &quot;main function&quot; according to amazon and it&#x27;s more for reading books. but why do you bring out such a device? you would only have to adapt the software, not even the hardware. i hope that either updates or an upcoming jailbreak will improve the situation.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How I am using a Macbook Pro 2009 in 2025</title>
        <published>2025-05-08T00:00:00+00:00</published>
        <updated>2025-05-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/how-i-am-using-a-macbook-pro-2009-in-2025/"/>
        <id>/blog/how-i-am-using-a-macbook-pro-2009-in-2025/</id>
        
        <content type="html" xml:base="/blog/how-i-am-using-a-macbook-pro-2009-in-2025/">&lt;h1 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h1&gt;
&lt;p&gt;This is a short blog post of me (&lt;em&gt;cashmere&lt;&#x2F;em&gt;) using a MacBook Pro 2009 in 2025.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;the-biggest-question-why&quot;&gt;The biggest question: WHY???&lt;&#x2F;h1&gt;
&lt;p&gt;In the current time, with all the great power and resources we got in the past years, I questioned myself more and more if we really need that much computation power and if it&#x27;s not possible to do the same tasks we do every day with much more weaker systems.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;choosing-the-right-system&quot;&gt;Choosing the right system&lt;&#x2F;h1&gt;
&lt;p&gt;When it came to choosing the right system for this experiment, there were only two systems, which were interesting for me. The first one was utilizing an old ThinkPad, and the second one was a good old chunky MacBook.&lt;&#x2F;p&gt;
&lt;p&gt;I already own two ThinkPads. Another reason why not to choose a ThinkPad was that they would run too well for this experiment. So it was the MacBook.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;specifications&quot;&gt;Specifications&lt;&#x2F;h1&gt;
&lt;p&gt;Here you can see the specs of my MacBook 2009:&lt;&#x2F;p&gt;
&lt;p&gt;Host: &lt;em&gt;MacBookPro5,5&lt;&#x2F;em&gt; Display: &lt;em&gt;1280x800 @ 60 Hz in 13 inch&lt;&#x2F;em&gt; CPU: &lt;em&gt;Intel® CoreTM2 ™2 Duo P7550 (2) @ 2.26 GHz&lt;&#x2F;em&gt; GPU: &lt;em&gt;NVIDIA GeForce 9400M&lt;&#x2F;em&gt; RAM: &lt;em&gt;4GB DDR2&lt;&#x2F;em&gt; Memory: &lt;em&gt;256GB SSD&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;first-impressions&quot;&gt;First impressions&lt;&#x2F;h1&gt;
&lt;p&gt;When the MacBook arrived, I was really overwhelmed by its big, chunky, but wonderful design. The device weighs 2kg. That&#x27;s way more than I ever thought.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;setting-up-the-device&quot;&gt;Setting up the device&lt;&#x2F;h1&gt;
&lt;p&gt;As every good software developer knows, &lt;em&gt;sigh&lt;&#x2F;em&gt;,&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;When an application is too slow, then its Frontend is written in JavaScript, or it&#x27;s based off Electron. &lt;em&gt;Screw you JavaScript&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h1 id=&quot;macos&quot;&gt;macOS&lt;&#x2F;h1&gt;
&lt;p&gt;At first, I tried my luck with running some semi-current version of macOS, as I somehow missed a pure UNIX environment. Another point was that since I have been using Linux now for over two years and made myself more familiar with UNIX and UNIX-like operating systems as Linux I was really excited about using macOS. Sadly the whole device was barely usable, and the last macOS version that supported this kind of MacBook was macOS El Capitan. And even this macOS version runs very sluggish.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;linux&quot;&gt;Linux&lt;&#x2F;h1&gt;
&lt;p&gt;I think it was predictable that this device was going to get Linux installed. Though I could write another blog post about this section, I want to keep it short.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;fedora-ubuntu&quot;&gt;Fedora &amp;amp; Ubuntu&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;em&gt;Fedora&lt;&#x2F;em&gt; was usable, but I still had a lot of problems as the newer Linux kernels didn&#x27;t support the proprietary Broadcom driver. Same goes for &lt;em&gt;Ubuntu&lt;&#x2F;em&gt;. Still, Ubuntu offered some nice help on how to install Linux (in this case, Ubuntu&#x27;s version of Linux LMAO&#x2F;) on a MacBook.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mx-linux&quot;&gt;MX Linux&lt;&#x2F;h2&gt;
&lt;p&gt;So I ended up with &lt;em&gt;MX Linux&lt;&#x2F;em&gt;. It runs perfect; they have a very intuitive installation; I was even able to encrypt the whole disk with very fast decryption at startup. I love MX Linux small utilities like &lt;em&gt;MX Tweaks&lt;&#x2F;em&gt; or &lt;em&gt;MX Tools&lt;&#x2F;em&gt;. It&#x27;s all in all a very great and neat Linux distribution with its own flavor, touch, and even applications.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;experience&quot;&gt;Experience&lt;&#x2F;h1&gt;
&lt;p&gt;I am currently using this MacBook to write this blog post. I can run Emacs, I was even able to use my whole Doom Emacs configuration. While it was a bit of a hassle to set it up, as MX Linux is based of Debian and Debian does not support the current version of Emacs (30.1), I was able to set it up after some time.&lt;&#x2F;p&gt;
&lt;p&gt;While I can not recommend it for tasks like web browsing websites with many Javascript, its really usuable for most things I could think of. I am even using it to write my Bachelor thesis and who would have thought. It&#x27;s more than efficient for this task.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;images&quot;&gt;Images&lt;&#x2F;h1&gt;
&lt;p&gt;Here are some obligatory images which I took for this blog post.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;tldr&quot;&gt;TLDR&lt;&#x2F;h1&gt;
&lt;p&gt;Nuke Mac OS and install &lt;em&gt;MX Linux&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With that being said -&amp;gt; &lt;em&gt;Happy Hacking&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hetzner StorageBox mounting with sops-nix for file storage &amp; Jellyfin streaming</title>
        <published>2025-04-28T00:00:00+00:00</published>
        <updated>2025-04-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="/blog/hetzner-storagebox-mounting-with-sops-nix-for-file-storage-jellyfin-streaming/"/>
        <id>/blog/hetzner-storagebox-mounting-with-sops-nix-for-file-storage-jellyfin-streaming/</id>
        
        <content type="html" xml:base="/blog/hetzner-storagebox-mounting-with-sops-nix-for-file-storage-jellyfin-streaming/">&lt;p&gt;After some tinkering, I finally have my Hetzner StorageBox mounted on my NixOS server-securely, declaratively, and ready for anything. The setup is not just robust, it&#x27;s also pretty slick: all credentials are managed with sops-nix, so there&#x27;s no plaintext password mess, and the mount is fully automated via systemd and NixOS config.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;why-hetzner-storagebox&quot;&gt;Why Hetzner StorageBox?&lt;&#x2F;h1&gt;
&lt;p&gt;Cheap and scalable storage, up to 20TB if needed.&lt;&#x2F;p&gt;
&lt;p&gt;Accessible via multiple protocols (CIFS&#x2F;SMB, SFTP, WebDAV).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Though I went with CIFS for native filesystem integration and best compatibility with Linux apps.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Data is protected with RAID, and snapshots are available for extra safety.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;mounting-with-nixos-sops&quot;&gt;Mounting with NixOS + sops&lt;&#x2F;h1&gt;
&lt;p&gt;My NixOS config uses cifs-utils for the mount and sops-nix for all secrets. The actual credentials are encrypted in a SOPS YAML file, and only decrypted at activation time. This means I can safely keep my config in git, and everything is reproducible and auditable.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
