Bringing jabber.el Back From the Dead

jabber.el is an XMPP client for Emacs, originally written in 2003. Development slowed over the years, though contributors kept the package working across Emacs releases. I took over as maintainer with the goal of modernizing the protocol support. Now, jabber.el is the most XEP-complete text-based client in existence. What Changed For those, like me, who count XEPs like Pokemon: OMEMO encryption (XEP-0384) via a C dynamic module wrapping picomemo OMEMO media sharing (XEP-0454) OpenPGP for XMPP (XEP-0373) using Emacs’ built-in EPG Stream Management (XEP-0198) with session resume Message Archive Management (XEP-0313) Message Carbons (XEP-0280) Delivery Receipts (XEP-0184) and Chat Markers (XEP-0333) Message Correction (XEP-0308), Replies (XEP-0461), Moderation (XEP-0424/0425) Chat State Notifications (XEP-0085) Client State Indication (XEP-0352) Blocking Command (XEP-0191) HTTP File Upload (XEP-0363) Direct TLS (XEP-0368) with dual SRV lookup Real Time Text (XEP-0301) PubSub (XEP-0060) Bookmarks (XEP-0402 with XEP-0048 fallback) SQLite message storage replacing flat-file history MUC Self-Ping (XEP-0410) Almost caught them all ...

2026/04/04

Gnosis 0.10: Import Anki, Merge Everything Into One

You can now import Anki decks into gnosis. The entire Anki ecosystem, thousands of community-maintained decks across every subject, is accessible from Emacs. I can finally keep track of the AnKing deck changes. If you can’t beat them, import them. Anki import gnosis-anki-import reads .apkg files and converts them into gnosis themata. It resolves Anki’s note type templates to extract question/answer pairs, normalizes tags, and strips Anki system tags like marked and leech. ...

2026/04/04

Gnosis: Design Mistakes

The more I use gnosis, the more I notice design faults inherited from the software I was previously using. Using decks for themata (flashcards/questions) Decks will be removed. Similarly to Anki, decks provided a restriction, not a feature. A thema can only belong to one deck, many-to-one, while tags are many-to-many. Themata in gnosis are already organized based on tags and you can customize the review algorithm per tag using gnosis-algorithm-custom-values. ...

2026/03/08

Gnosis 0.8.0 Release Notes

I’m excited to announce the release of version 0.8.0 for gnosis. Finally this project is now evolving into the “all-in-one” knowledge system I’ve envisioned. This version allows for viewing of linked nodes of org-gnosis and their linked themata in a tabulated-list via the gnosis-dashboard with excellent performance. No more external browsers needed to view my collection. This means the org-gnosis-ui project should be considered deprecated. All functionalities can now be performed within Emacs. ...

2026/03/05

Gnosis 0.7.0 Release Notes

I’ve finally published Gnosis version 0.7.0 that brings some much needed changes and integration with org-gnosis. You can get the latest version of gnosis via GNU ELPA or directly from upstream. New features Review topic from dashboard nodes view (r), with configurable forward-link and backlink depth (R or C-u r). gnosis-review-topic accepts separate forward/backlink depth to include themata from related nodes. gnosis-save-hook runs after saving a thema, called with the thema ID. Link integrity detection and repair commands (gnosis-links-check, gnosis-links-sync). Dashboard maintenance menu for syncing/rebuilding nodes and link health checks. Dashboard shows themata with orphaned links. View due org-gnosis nodes linked to themata from dashboard. Bulk replace string in keimenon with org-gnosis node link. Custom gnosis-center-content-during-review option. Delete action available during review. Format org-gnosis links in keimenon during review output. Export deck option to include or exclude suspended themata. Exported decks include a #+THEMATA: header with thema count. Importing into an existing deck prompts for confirmation. Failed thema imports report the source file line number. Dashboard Added nodes dashboard, view org-gnosis nodes information including backlinks and linked themata as well as start a review session. Suspend column displays Yes No instead of 1 0. Flatten Actions submenu into the home menu. Separate Import/Export into its own menu column. Four-column layout: Navigate, Actions, Import/Export, Maintenance. Algorithm Cap gnosis-synolon at gnosis-algorithm-synolon-max (default 3.0), floor at 1.3. Add interval fuzz to prevent review clustering. Fix lethe event: properly reduce gnosis-plus on consecutive failures. Performance Dashboard suspend, delete, and edit update only the affected entry instead of refreshing the entire buffer. Dashboard nodes view uses bulk queries for link counts (2 queries instead of 2N). Deck export uses 2 bulk queries instead of 2 per thema (N+1 eliminated). Deck export uses plain text insertion instead of per-thema buffer scans (O(n^2) eliminated). Deck import wraps all operations in a single transaction with pre-cached IDs (10K fsyncs reduced to 1). Review updates use a single DB query. Tag output uses a single DB call. Average daily reviews computed with a single DB call. Bug fixes Fix gnosis-monkeytype hook leak (now buffer-local). Fix vc-pull to reopen database properly after successful pull. Pre-load emacsql-sqlite-builtin to fix cl-generic dispatch crash on Emacs 29+. Documentation Update Introduction to describe the intended workflow with org-gnosis (write notes, create themata, link, review). Document the two separate databases (gnosis and org-gnosis). Update dashboard section for new menu layout. Add Import & Export section with export options and import behavior.

2026/02/22

Org Gnosis 0.2.0 Release Notes

I just pushed a new version for org-gnosis, the note taking module of gnosis, which you can find here. The update should be available to all users via GNU ELPA. Important Changes Database Changes Database version bumped to 3, tracking mtime and hash for both nodes and journal files. Automatic database migration prompts when schema is outdated. Lazy database initialization - database connections are created only when needed, improving startup time. Added org-gnosis-database-file custom variable to specify custom database file location. Performance Improvements Major performance improvements for org-gnosis-db-sync with GC optimization during sync. Two-tier incremental sync: fast mtime check, then accurate hash comparison. Only processes files where both modification time and content have changed. Dramatically improves performance for .gpg encrypted files and large repositories. Both node files and journal files now use incremental sync with progress reporting showing changed/total file counts. To force full resync, call org-gnosis-db-sync with prefix arg C-u. e.g C-u M-x org-gnosis-db-sync RET. Journaling By default, today’s journal entries are created in org-gnosis-journal-file as level 1 headings. When set to nil, creates separate files for each date entry. Creating new entries (e.g., via org-gnosis-journal-find for an event, non-date) creates separate files in org-gnosis-journal-dir regardless of this setting. Single journal file is only used for today’s date entries. Added org-gnosis-journal-as-gpg that when non-nil journal files will be created as gpg encrypted files. Journal todos now only retrieve checkboxes from today’s heading when using a single journal file, improving performance. Tag Management Automatic cleanup of orphaned tags (tags with no associated nodes) when updating files. Improved tag-based node selection with dedicated functions. Improvements Simplified parsing algorithm for better performance and maintainability. Better handling of topic titles - only includes parent headings when they have IDs. Added org-gnosis-get-nodes-data for retrieving node information with backlink counts. Improved test coverage for parsing, title processing, and journal todos.

2026/02/22

(Video) Contributing to Git Projects with Magit: PRs, Patches & Agit workflow

Contributing to Git Projects with Magit: PRs, Patches & Agit workflow Quick video guide on contributing to git projects using Magit. Showing an overview of the 3 most commonly used workflows Pull Requests Agit Workflow Git patches Video notes: Introduction I’m creating this as a tutorial video on how to contribute to bebliotheca, a digital recreation of the Library of Constantinople to host texts that would have been found there during the Greco-Roman Empire. ...

2026/02/06

(Video) Emacs Notmuch with Multiple Addresses & Auto Encryption

This guide provides a quick setup for configuring Notmuch with GNU Emacs to handle multiple email addresses and enable automatic encryption. Notmuch has been incredibly useful for me over the past year, and I hope this guide helps new users overcome initial challenges. Emacs Notmuch with Multiple Addresses & Auto Encryption Video notes: Summary Emacs email workflow demo using notmuch.el. Sending mails from multiple addresses, using smtpmail. Auto encrypt emails, if a pgp key is available, using mml-sec. Why notmuch Builtin Emacs support, with notmuch.el. Packages such as ol-notmuch bring integration with the rest of the Emacs ecosystem. Notmuch is a tag based system. You do not rely on your email provider for filter rules etc to organize your emails into separate mailboxes. Which is inefficient to begin with when working with thousands++ of emails. This also makes moving to a new email provider easier. Locally storing mail. Great performance for filtering and searching through hundred of thousand mails. Assumptions that I make for this video You have a working Emacs configuration Your mail providers has support for retrieving and sending mail via 3rd party apps You already know how to setup isync/mbsync to retrieve emails from remote server. Your mail provider offers smtp credentials to use third party applications. I personally recommend trying out purelymail.com only costs 10$/year and offers good service. Example isyncrc configuration ~/.config/isyncrc ...

2025/12/18

Daily Driving a Raspberry Pi 5

After switching from Apple devices to GNU/Linux, I’ve enjoyed numerous advantages. However, there’s always been one thing that used to make me look back: battery life, or the lack thereof. Not anymore :) ...

2025/10/31

Emacs Everywhere, even in Wayland

If you are anything like me, you probably feel something is wrong whenever you have to input text outside of Emacs. Fear not, there’s a solution. Here’s a simple code snippet to launch an emacs temp frame for input instead. (defun thanos/wtype-text (text) "Process TEXT for wtype, handling newlines properly." (let* ((has-final-newline (string-match-p "\n$" text)) (lines (split-string text "\n")) (last-idx (1- (length lines)))) (string-join (cl-loop for line in lines for i from 0 collect (cond ;; Last line without final newline ((and (= i last-idx) (not has-final-newline)) (format "wtype -s 350 \"%s\"" (replace-regexp-in-string "\"" "\\\\\"" line))) ;; Any other line (t (format "wtype -s 350 \"%s\" && wtype -k Return" (replace-regexp-in-string "\"" "\\\\\"" line))))) " && "))) (defun thanos/type () "Launch a temporary frame with a clean buffer for typing." (interactive) (let ((frame (make-frame '((name . "emacs-float") (fullscreen . 0) (undecorated . t) (width . 70) (height . 20)))) (buf (get-buffer-create "emacs-float"))) (select-frame frame) (switch-to-buffer buf) (erase-buffer) (org-mode) (setq-local header-line-format (format " %s to insert text or %s to cancel." (propertize "C-c C-c" 'face 'help-key-binding) (propertize "C-c C-k" 'face 'help-key-binding))) (local-set-key (kbd "C-c C-k") (lambda () (interactive) (kill-new (buffer-string)) (delete-frame))) (local-set-key (kbd "C-c C-c") (lambda () (interactive) (start-process-shell-command "wtype" nil (thanos/wtype-text (buffer-string))) (delete-frame))))) Make sure wtype is installed in your system for the above snippet to work. ...

2025/07/19