<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="https://plaindrops.de/assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Plain DrOps (Posts about emacs)</title><link>https://plaindrops.de/</link><description></description><atom:link href="https://plaindrops.de/categories/emacs.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2025 &lt;a href="mailto:andy@plaindrops.de"&gt;Andy Drop&lt;/a&gt; </copyright><lastBuildDate>Tue, 16 Dec 2025 13:28:45 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>My 10 Years with Emacs</title><link>https://plaindrops.de/blog/2025/tenyearsofemacs/</link><dc:creator>Andy Drop</dc:creator><description>&lt;p&gt;
Today, 10 years ago, I had my first encounter with Emacs, and that day definitely changed the way I work with computers—if not my entire life.
&lt;/p&gt;
&lt;!-- TEASER_END --&gt;

&lt;p&gt;
I remember that day so clearly because it was the day after the very first meeting of the "Warpzonista Coding Club." At that time, the Warpzone was my local hackerspace, and its focus was mainly on hardware tinkering. I wanted to meet more people who, like me, were into programming, and while enjoying the most beautiful sunshine and some light &lt;a href="https://www.youtube.com/watch?v=d_siG4dY6qs"&gt;Son Cubano&lt;/a&gt; music, the idea of founding the Coding Club came to me. The first meeting took place on February 27, 2015. After a brief introduction, the conversation naturally turned to a topic every programmer eventually has to decide for themselves: their choice of text editor.
&lt;/p&gt;

&lt;p&gt;
Since I was mainly coding professionally at the time, I used the integrated development environment that Microsoft shipped with Visual Basic 6. However, I wanted to program in Python on Linux and was looking for a good editor. I had already tried Vim before, but something about it didn't sit right with me. That evening, I met &lt;a href="https://wwwtech.de/about"&gt;Christian Kruse&lt;/a&gt;, and we talked about how my mind works—I naturally think in hierarchies. Trees are my thing; I approach problems by backtracking through different solutions, and I break down projects into tasks and sub-tasks.
&lt;/p&gt;

&lt;p&gt;
He then said: "Then Org mode will be your thing," and gave me a quick overview on his laptop. The next day, I installed Emacs and tried to get a feel for it myself. To cut a long story short: Org mode was amazing, but I absolutely couldn’t get used to the way Emacs worked. Christian had already warned me, and I knew I needed something called CUA mode. A bit of Googling led me to my first configuration files, which others had shared on the internet.
&lt;/p&gt;
&lt;h2 class="collapsible" id="orgcc88dbe"&gt;The First Configs&lt;/h2&gt;
&lt;div id="outline-container-orgcc88dbe" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-orgcc88dbe"&gt;
&lt;p&gt;
I spent a few weeks putting together a usable configuration. I gathered some snippets from various places online. CUA mode was included, YASnippet as well, and I discovered that I could create my own keybindings. At the time, I didn't know I could set keybindings per mode, so I made them all global, which, of course, didn’t take long before my first "config bankruptcy," a term I wasn’t familiar with back then. The main reason was that the configuration snippets I copied often came with their own namespaces, which I didn’t recognize at first.
&lt;/p&gt;

&lt;p&gt;
My second approach to configuring Emacs was much closer to what I still use today. I had read a lot in the Emacs manual, understood keybinding layers, and also realized that when copying other people's configurations, it was crucial to adapt them to my package manager. My second config was therefore much more structured.
&lt;/p&gt;

&lt;p&gt;
I set up a minimal ini.cfg that did nothing except loading three other configuration files:
&lt;/p&gt;

&lt;ul class="org-ul"&gt;
&lt;li&gt;A base configuration where I defined my preferred settings for each installed package (except for keybindings).&lt;/li&gt;
&lt;li&gt;A keybinding configuration that contained all keybindings in one place—this way, I thought, I wouldn’t accidentally create conflicts.&lt;/li&gt;
&lt;li&gt;A custom adjustments file where any changes made through Emacs' built-in configuration tools would go.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
This setup worked well for about 1–2 years. Over time, I became more familiar with Emacs, learning how CTRL-X and CTRL-C serve as entry points into the entire keyboard system. I began to appreciate how well-thought-out and sensible Emacs' defaults were, but they still didn’t work with my brain. A big step forward was discovering the Hydra package. But first, Ledger
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="orgb7c98fc"&gt;Ledger&lt;/h2&gt;
&lt;div id="outline-container-orgb7c98fc" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-orgb7c98fc"&gt;
&lt;p&gt;
One of the first packages that had a real impact on my daily life was Ledger mode. Ledger is a plain-text double-entry bookkeeping system. I quickly started writing my bank transactions into a file. With a bit of thought, I even managed to implement my grandmother’s envelope budgeting system. This ended up saving my finances by giving me complete clarity over my money.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="orgcba2065"&gt;Hydra&lt;/h2&gt;
&lt;div id="outline-container-orgcba2065" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-orgcba2065"&gt;
&lt;p&gt;
Up until that point, I had two ways to call functions: either through a keybinding or by looking up the function name online and calling it via M-X. With Hydra, I could now group important functions together, making them available only in relevant modes. I became a huge Hydra fan and eventually consolidated all my Hydras into a single file, which evolved into my Project Medusa, now the fourth file in my Emacs configuration.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="org646c5bf"&gt;Helm&lt;/h2&gt;
&lt;div id="outline-container-org646c5bf" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org646c5bf"&gt;
&lt;p&gt;
The next big improvement was Helm. Choosing from multiple options in the minibuffer, especially for M-x, was a pain. Helm provided a much more comfortable interface. I could even display results in a separate buffer within the same window or in a neighboring window.
&lt;/p&gt;

&lt;p&gt;
Although things were already much better, a &lt;a href="https://protesilaos.com/codelog/2020-01-07-emacs-display-buffer/"&gt;Video&lt;/a&gt; by Prot made me rethink my approach to window management. Since then, I have replaced Helm with what I call the VOCEM stack.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="org5b25320"&gt;VOCEM&lt;/h2&gt;
&lt;div id="outline-container-org5b25320" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org5b25320"&gt;
&lt;p&gt;
VOCEM stands for Vertico, Orderless, Consult, Embark, and Marginalia. Many Emacs users have adopted this combination, though each package can also be used separately:
&lt;/p&gt;

&lt;dl class="org-dl"&gt;
&lt;dt&gt;Vertico&lt;/dt&gt;&lt;dd&gt;provides a fast and minimalistic vertical completion UI.&lt;/dd&gt;
&lt;dt&gt;Orderless&lt;/dt&gt;&lt;dd&gt;allows for flexible, out-of-order completion.&lt;/dd&gt;
&lt;dt&gt;Consult&lt;/dt&gt;&lt;dd&gt;offers enhanced search and navigation tools.&lt;/dd&gt;
&lt;dt&gt;Embark&lt;/dt&gt;&lt;dd&gt;acts like a context menu, making it easy to take actions on items near the cursor.&lt;/dd&gt;
&lt;dt&gt;Marginalia&lt;/dt&gt;&lt;dd&gt;adds helpful annotations to minibuffer completions.&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="org209feac"&gt;Denote&lt;/h2&gt;
&lt;div id="outline-container-org209feac" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org209feac"&gt;
&lt;p&gt;
Denote had just as much of an impact on me as Orgmode. Long before Emacs, I had been trying to organize all the loose thoughts, ideas, and sources that I otherwise carried around in my head on my computer. Similar to how Luhmann, here in the region, worked with his legendary Zettelkasten. Either the approaches didn't work for me at all, or the filing system (which always maintained some kind of external index of the knowledge) eventually lost sync between the knowledge and the index. Denote attaches all metadata directly to the file, and so, even when sharing across all my devices, I have never managed to throw my mental exoskeleton out of sync. A great, well-thought-out piece of software.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="orga1d4b4a"&gt;Things I Intentionally Avoid&lt;/h2&gt;
&lt;div id="outline-container-orga1d4b4a" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-orga1d4b4a"&gt;
&lt;ul class="org-ul"&gt;
&lt;li&gt;For example, I do not use a package tool that keeps the entire configuration for a package in one place. I deliberately want all keybindings for all packages in one location, and the same goes for my Hydras. These build on each other, and it is practical to have them all in a single file without other distractions.&lt;/li&gt;
&lt;li&gt;Zettelkasten. I don't know the software, but I have a strongly negative opinion about the digitization of Luhmann's concept. It's the year 2025, and the hyperlink has been invented.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="org302c484"&gt;Conclusion&lt;/h2&gt;
&lt;div id="outline-container-org302c484" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org302c484"&gt;
&lt;p&gt;
The path I have taken over these 10 years is just one of thousands of possible ways. Everyone uses Emacs for different things, and every mind works differently. I can definitely recommend carefully considering your own requirements for the Emacs environment:
&lt;/p&gt;

&lt;ol class="org-ol"&gt;
&lt;li&gt;Take a short note whenever something feels "wrong" to you. Eliminate these things from time to time.&lt;/li&gt;
&lt;li&gt;Try to figure out what kinds of things you want to work with in Emacs: Configs? Novels? Accounting files? Addresses? Emails? Websites? Quotes? Places? This list could go on indefinitely.&lt;/li&gt;
&lt;li&gt;For each of these things, make a list of the actions you commonly perform on them. For example, web links: Open in browser, open in external browser, save, publish in blog, sync across all devices, etc.&lt;/li&gt;
&lt;li&gt;Gradually build your personal workflow from these elements.&lt;/li&gt;
&lt;li&gt;Don’t do this directly on the computer, write these thoughts down on paper and keep this workflow as a battle plan for yourself.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="org0c09fcd"&gt;Thanks&lt;/h2&gt;
&lt;div id="outline-container-org0c09fcd" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org0c09fcd"&gt;
&lt;p&gt;
Of course, I want to start by thanking &lt;a href="https://wwwtech.de/about"&gt;Christian Kruse&lt;/a&gt;, who nudged me in the right direction 10 years ago. But also a few other people (and I’ll surely forget some in the end). As a bonus, you’ll get to know how I refer to these people in my mind.
&lt;/p&gt;

&lt;ul class="org-ul"&gt;
&lt;li&gt;&lt;a href="https://sachachua.com/blog/"&gt;Sacha Chua&lt;/a&gt;, the "Mother of the Company," for her tireless work in keeping the Emacs community connected through her Emacs News and the annual Emacs Conference. She also regularly documents the real-world problems she solves and the methods she uses, explaining why they work.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://protesilaos.com/"&gt;Protesilaos "Prot" Stavrou&lt;/a&gt;, "The Philosopher," for Denote and especially for openly sharing his thoughts on designing Emacs packages in his blog. This makes it easy to understand whether his packages align with one’s personal workflow.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://karl-voit.at/"&gt;Karl Voit&lt;/a&gt;, "Mr. PIM," for his fantastic Org-mode talk and the idea of rethinking how one manages personal information from the ground up. I came to different conclusions than he did, but through this, I learned how my brain works and that it makes sense to embrace its differences.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fosstodon.org/@daviwil"&gt;David Wilson&lt;/a&gt;, "The Explainer-in-Chief", for his countless System Crafters videos, which are always helpful when you need something explained in great detail.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Many others, whose ideas I’ve read here and there, have also grown close to my heart.
&lt;/p&gt;

&lt;p&gt;
Here’s to the next 10 years with all of you.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description><category>emacs</category><category>orgmode</category><guid>https://plaindrops.de/blog/2025/tenyearsofemacs/</guid><pubDate>Tue, 16 Dec 2025 08:13:00 GMT</pubDate></item><item><title>EmacsWiki Blog Carnival "Maintenance"</title><link>https://plaindrops.de/blog/2025/emacscarnival/</link><dc:creator>Andy Drop</dc:creator><description>&lt;p&gt;
In October, as the days grow shorter and the air turns sharper, many people naturally shift their focus from the creative energy of summer to the quieter work of maintenance. It’s the season of clearing gutters, deep-cleaning corners of the house that have been ignored, and tending to the small repairs that keep daily life running smoothly. Just as some turn to housekeeping and autumn cleaning, others return to digital upkeep — reviewing notes, pruning old files, or fine-tuning their Emacs configuration so it feels nice and reliable. "Maintenance", in whatever meaning will be the topic of the EmacsWiki Blog Carnival in October.
&lt;/p&gt;
&lt;!-- TEASER_END --&gt;
&lt;h2 class="collapsible" id="org5afeaea"&gt;What’s a Blog Carnival, Again?&lt;/h2&gt;
&lt;div id="outline-container-org5afeaea" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org5afeaea"&gt;
&lt;p&gt;
&lt;small&gt;(Copied from Christian Tietzes introductory post)&lt;/small&gt;
&lt;/p&gt;

&lt;p&gt;
This is our first Emacs Carnival, so you may not know the format. A blog carnival is a fun way to tie together a community with shared writing prompts, and marvel at all the creative interpretations of the topic of the month. I’ve provided a couple of interpretations above, but you may think of something else entirely. That’s amazing, roll with it, that’s what makes this fun!
&lt;/p&gt;

&lt;p&gt;
For future Carnivals, check out the &lt;a href="https://www.emacswiki.org/emacs/Carnival"&gt;“Carnival” page on EmacsWiki&lt;/a&gt;. It includes instructions, and is our community space to coordinate participants and topic ideas.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="org5d5ea41"&gt;Submissions&lt;/h2&gt;
&lt;div id="outline-container-org5d5ea41" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org5d5ea41"&gt;
&lt;p&gt;
Just &lt;a href="https://masto.plaindrops.de/@spacecadet"&gt;DM&lt;/a&gt; / &lt;a href="mailto:carnival@plaindrops.de"&gt;email&lt;/a&gt; me with your submission! When I find a post elsewhere I will link it here, also. I’ll collect submissions up to, and including, November 1st (Central European Time), so that every time zone has had a chance to meet the October 30th deadline :)
&lt;/p&gt;


&lt;p&gt;
These have been submitted as of 2025-10-30:
&lt;/p&gt;

&lt;ul class="org-ul"&gt;
&lt;li&gt;&lt;a href="https://www.finaprosadigital.com/2025-10-12-maintenance-(mantenimiento).html"&gt;Maintenance (Mantenimiento)&lt;/a&gt; by Carlos Pajuelo&lt;/li&gt;
&lt;li&gt;&lt;a href="https://macadie.info/2025/10/08/emacs-carnival-maintenance/"&gt;Emacs Carnival: Maintenance&lt;/a&gt; by Eric MacAdie&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mike.hostetlerhome.com/emacs-maintenance"&gt;Emacs Maintenance&lt;/a&gt; by Mike Hostetler&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kyo.iroiro.party/en/posts/emacs-maintains-my-arch/"&gt;Using Emacs Org-mode As My Package Manager&lt;/a&gt; by Kana&lt;/li&gt;
&lt;li&gt;&lt;a href="https://christiantietze.de/posts/2025/10/sharpening-the-saw-with-emacs/"&gt;Sharpening the Saw with Emacs&lt;/a&gt; by Christian Tietze&lt;/li&gt;
&lt;li&gt;&lt;a href="https://curious.port111.com/2025/10/30/its-fall-time-to-clean.html"&gt;It's Fall. Time to clean up my emacs clutter.&lt;/a&gt; by George Jones&lt;/li&gt;
&lt;li&gt;&lt;a href="https://quijotelibre.net/blog/sharpening-axe-preparing-soil-harvest/"&gt;Sharpening the axe (or preparing the soil for the harvest)&lt;/a&gt; by Quijote Libre  (also in &lt;a href="https://quijotelibre.net/blog/afilar-hacha-preparar-tierra-cosecha/"&gt;spanish&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://commonplace.doubleloop.net/emacs-carnival-praise-the-patchers"&gt;Emacs Carnival: Praise the patchers&lt;/a&gt; by Neil&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Thanks everyone for participating!
&lt;/p&gt;

&lt;p&gt;
November is being hosted by &lt;a href="https://donaldh.wtf/about/"&gt;Donald Hunter&lt;/a&gt;: &lt;a href="https://donaldh.wtf/2025/10/emacs-carnival-2025-11-an-ode-to-org-babel/"&gt;An ode to org-babel&lt;/a&gt;. You can also be host of a future carnival yourself, don’t be shy :)
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description><category>Carnival</category><category>emacs</category><category>Maintenance</category><guid>https://plaindrops.de/blog/2025/emacscarnival/</guid><pubDate>Mon, 29 Sep 2025 00:00:00 GMT</pubDate></item><item><title>Collecting and Categorizing Web Links in Org-mode</title><link>https://plaindrops.de/blog/2025/tagwood/</link><dc:creator>Andy Drop</dc:creator><description>&lt;p&gt;
Whether they’re called bookmarks, favorites, or weblinks, we all accumulate a large number of them over time. At some point, it all becomes overwhelming and needs organizing. So, I wrote a Python tool for that. 
&lt;/p&gt;
&lt;!-- TEASER_END --&gt;
&lt;h2 class="collapsible" id="orgd9a2b66"&gt;What Has Happened So Far&lt;/h2&gt;
&lt;div id="outline-container-orgd9a2b66" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-orgd9a2b66"&gt;
&lt;p&gt;
New weblinks always originate from my browser. whether it's Firefox on my desktop and laptop or on my phone. I could simply leave them in Firefox, allowing me to sync and access them across devices. Sounds good enough, right?
&lt;/p&gt;

&lt;p&gt;
But I also maintain a &lt;a href="https://plaindrops.de/page/links/"&gt;page with links&lt;/a&gt; on this blog that I want to share publicly. Ideally, I wouldn’t have to manage these links separately. That’s why, years ago, I decided not to use built-in or online bookmark managers. Instead, I store all my weblinks as plaintext in Orgmode format. Each link is a heading with the page title, linked to the respective URL.
&lt;/p&gt;

&lt;p&gt;
If I feel like it, I add a short note or a quote from the page. On my laptop and desktop, a small browser add-on (Org Capture) appends new links to my Links.org file using Emacs’ org-capture protocol. On my phone, this add-on doesn’t work, so I share the page with the &lt;a href="https://github.com/orgzly-revived/orgzly-android-revived"&gt;Orgzly-revived&lt;/a&gt; app, which lets me edit Org-mode files on Android. The link also ends up in Links.org, and I sync my entire &lt;i&gt;org&lt;/i&gt; directory across all my devices.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="org72f6bbb"&gt;The Links.org File in Detail&lt;/h2&gt;
&lt;div id="outline-container-org72f6bbb" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org72f6bbb"&gt;
&lt;p&gt;
The file starts with a set of metadata lines that my static site generator needs to create the public link page. It looks like this:
&lt;/p&gt;
&lt;pre class="example" id="org7466407"&gt;
#+BEGIN_COMMENT
.. title: Links
.. description: All the links I can recommend
.. slug: links
.. date: 2019-01-01 00:00:00 UTC+01:00
.. tags: links, emacs, orgmode, qutebrowser, plaintext, pim
.. previewimage: qrcodebus.png
#+END_COMMENT
#+OPTIONS: tags:nil
&lt;/pre&gt;
&lt;p&gt;
The last line ensures that tags assigned to individual links aren’t exported to HTML.
&lt;/p&gt;

&lt;p&gt;
All new links start as second-level headings. The first-level headings are divided into four sections:
&lt;/p&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="org08e3943"&gt;1. Quicklinks&lt;/h3&gt;
&lt;div id="outline-container-org08e3943" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-org08e3943"&gt;
&lt;p&gt;
These are my frequently used links, marked with :noexport:, so they don’t appear in the public link list. They are placed at the top of the file for quick access.
&lt;/p&gt;
&lt;pre class="example" id="orga0b65c9"&gt;
* ------ Quick Links ----- :noexport:
 :PROPERTIES:
 :VISIBILITY: children
 :END:
&lt;/pre&gt;
&lt;table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"&gt;


&lt;colgroup&gt;
&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th scope="col" class="org-left"&gt;Social Media&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Shopping&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;News&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Finanzen&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Haustechnik&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Konten&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Other&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="org-left"&gt;&lt;a href="https://chaos.social"&gt;Mastodon&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="https://idealo.de"&gt;Idealo&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="https://tagesschau.de"&gt;Tagesschau&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="https://www.volksbank-eg.de/services_cloud/portal/"&gt;Volksbank&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="http://fritz.box/"&gt;FritzBox&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="https://bibload.onleihe.de/"&gt;BibLoad&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="https://www.thingiverse.com/"&gt;Thingiverse&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;&lt;a href="https://feddit.de"&gt;Feddit&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="https://www.amazon.de/"&gt;Amazon&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="https://www.theguardian.com/europe"&gt;The Guardian&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="https://banking.barclays.de/Login"&gt;Barclays&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="http://192.168.9.32"&gt;Wechselrichter&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="https://sb-warendorf.lmscloud.net/"&gt;Stadtbücherei&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="https://cults3d.com/de"&gt;Cults&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="https://www.ebay.de/"&gt;eBay&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="https://www.schwaebisch-hall.de/meinkonto/login-mein-konto.html"&gt;Schw. Hall&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="http://192.168.9.38/"&gt;Stromzähler&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;&lt;a href="https://codeberg.org/user/login"&gt;Codeberg&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="https://www.otto.de/"&gt;Otto&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="https://kachelmannwetter.com/de/wetter/2814127-warendorf"&gt;Wetter WAF&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="https://www.paypal.com/signin"&gt;Paypal&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="http://192.168.9.25:8123"&gt;Home Assistant&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="https://configure.zsa.io/my_layouts"&gt;Oryx&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;&lt;a href="https://app.wallabag.it/"&gt;Wallabag&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="https://www.kaufland.de/"&gt;Kaufland&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="https://www.destatis.de/DE/Home/_inhalt.html"&gt;Stat. Bundesamt&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="http://127.0.0.1:631/"&gt;CUPS&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="https://www.dashboard-deutschland.de/"&gt;Dashboard DE&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="http://127.0.0.1:8081/"&gt;Syncthing&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;&lt;a href="https://chat.openai.com"&gt;ChatGPT&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="https://de.statista.com/"&gt;Statista&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;&lt;a href="http://localhost:8080/"&gt;Jenkins&lt;/a&gt;&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;Wiki&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="org244d84a"&gt;2. Public Links&lt;/h3&gt;
&lt;div id="outline-container-org244d84a" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-org244d84a"&gt;
&lt;p&gt;
These links are visible on the blog. My site generator processes this section and turns it into a dynamic list using a bit of CSS magic.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="orge1c3def"&gt;3. Private Links&lt;/h3&gt;
&lt;div id="outline-container-orge1c3def" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-orge1c3def"&gt;
&lt;p&gt;
This is where things get interesting. Right now (March 4, 2025), this section holds around 450 links, categorized with up to four tags. The organization, however, is… let’s say, questionable. More of a dumpster fire, really.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="orgebfdfb4"&gt;4. The INBOX&lt;/h3&gt;
&lt;div id="outline-container-orgebfdfb4" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-orgebfdfb4"&gt;
&lt;p&gt;
Basically, the same chaotic mess as the private links. just without any tags assigned yet.
&lt;/p&gt;

&lt;p&gt;
So, my tool’s job is to process sections 3 and 4.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="orgb69f609"&gt;What’s the Goal?&lt;/h2&gt;
&lt;div id="outline-container-orgb69f609" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-orgb69f609"&gt;
&lt;p&gt;
The tool should take all weblinks from sections 3 and 4 and organize them into one logical tree structure based on their tags. The tricky words here are &lt;b&gt;one&lt;/b&gt; and &lt;b&gt;logical&lt;/b&gt;.
&lt;/p&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="orgb194b95"&gt;Are There Multiple Possible Trees?&lt;/h3&gt;
&lt;div id="outline-container-orgb194b95" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-orgb194b95"&gt;
&lt;p&gt;
Of course, otherwise, it would be too easy. Tags are inherently non-hierarchical. If I tag a link with a and b
&lt;/p&gt;
&lt;pre class="example" id="org97580fb"&gt;
* Link :a:b:
&lt;/pre&gt;

&lt;p&gt;
I can create two different trees:
&lt;/p&gt;
&lt;pre class="example" id="orge8c9bf0"&gt;
├── a
│   └── b
│       └── Link
└── b
    └── a
        └── Link
&lt;/pre&gt;

&lt;p&gt;
As soon as I have three tags, I can insert the additional tag at three different levels. in each of the two trees. resulting in six possible trees.
&lt;/p&gt;

&lt;p&gt;
The mathematical representation is 3! (i.e., 3 factorial). If anyone remembers exponential growth from the COVID era, that’s nothing compared to factorial growth. it’s child’s play in comparison.
&lt;/p&gt;

&lt;p&gt;
With six tags, we’re already at 720 possible trees, and just eight tags result in 40,320 trees.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="org84769f2"&gt;And what do I do with all these trees?&lt;/h3&gt;
&lt;div id="outline-container-org84769f2" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-org84769f2"&gt;
&lt;p&gt;
The common approach would be to use them all. That means a link with four tags would appear 24 times in the link list. but there would also be 24 ways to find it. Roughly estimated, my 450 links would result in about 3,000 links in the output file. And that’s too much for me.
&lt;/p&gt;

&lt;p&gt;
Many of these paths wouldn’t even make sense. Suppose I bookmark the location where I last parked my car:
&lt;/p&gt;
&lt;pre class="example" id="orgc673f51"&gt;
* Auto :germany:munic:mainstreet:
&lt;/pre&gt;
&lt;p&gt;
Then I don’t think, "Hmm, I remember parking on Main Street, so show me all the countries that have cities with a Main Street so I can pick the right one."
&lt;/p&gt;

&lt;p&gt;
So, I need to cut down the trees that don’t make sense. This brings in the second key word: the structure should be a logical tree. But, as should have been clear even before Trump, there are some pretty strange interpretations of logic. and that’s not even considering alternative logic.
&lt;/p&gt;

&lt;p&gt;
Computers aren’t particularly good at determining what makes sense in a search. So instead, I rely on a different criterion: frequency. Because counting is something computers are really good at.
&lt;/p&gt;

&lt;p&gt;
If my file contains the tag emacs 200 times but the tag orgmode only 100 times, then the tree looks like this:
&lt;/p&gt;
&lt;pre class="example" id="orgc164ff5"&gt;
└── emacs
    └── orgmode
        └── Link
&lt;/pre&gt;

&lt;p&gt;
That works pretty well, but now and then, some strange hierarchies still appear. especially with tags that are rarely used overall. In those cases, a single extra use can already make a difference in how the sorting plays out.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="orgf100483"&gt;And now I’m even cheating a little.&lt;/h3&gt;
&lt;div id="outline-container-orgf100483" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-orgf100483"&gt;
&lt;p&gt;
In most cases, rare tags don’t really matter. But when this happens with major (frequent) tags, it can be quite annoying. That’s why I cheat a bit.
Sticking with the car example, I’d actually write it like this:
&lt;/p&gt;
&lt;pre class="example" id="orgb50ae62"&gt;
* Auto :Germany:Munic:mainstreet:
&lt;/pre&gt;
&lt;p&gt;
See the difference? The first two tags are now capitalized. For my tool, this signals that country and city are hierarchically more important than the street. This still leaves two possible trees, but it eliminates four others right away. I can only enforce one strict hierarchy level this way, but it helps handle the edge cases quite well.
&lt;/p&gt;

&lt;p&gt;
Why is this cheating? Well, according to the textbook, tags don’t carry hierarchical information, and my programmer’s heart does feel a little dirty about it.
&lt;/p&gt;

&lt;p&gt;
Now, on to the technical part, in case anyone wants to implement this in another language:
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="orga8b13b7"&gt;The Algorithm&lt;/h2&gt;
&lt;div id="outline-container-orga8b13b7" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-orga8b13b7"&gt;
&lt;ol class="org-ol"&gt;
&lt;li&gt;Collecting Links:
&lt;ul class="org-ul"&gt;
&lt;li&gt;First, I gather all the links I want to process and store them in a dictionary.&lt;/li&gt;
&lt;li&gt;The key is a hash of the actual link, which eliminates accidental duplicates.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;

&lt;li&gt;Generating Permutations:
&lt;ul class="org-ul"&gt;
&lt;li&gt;I generate all possible tag permutations.&lt;/li&gt;
&lt;li&gt;Any permutations that violate my "cheated" tag hierarchy are skipped.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;

&lt;li&gt;Building the Tree:
&lt;ul class="org-ul"&gt;
&lt;li&gt;The list of links is passed into the core function that constructs the tree.&lt;/li&gt;
&lt;li&gt;Since trees lend themselves well to recursion, the function is recursive.&lt;/li&gt;
&lt;li&gt;Each function call processes one hierarchy level and then calls itself for deeper levels.&lt;/li&gt;
&lt;li&gt;The recursion stops when there are no more links left that don’t already belong to a tag.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;

&lt;li&gt;Inside the Recursive Function:
&lt;ul class="org-ul"&gt;
&lt;li&gt;The current tag is added as a node in the tree.&lt;/li&gt;
&lt;li&gt;All links that fit exactly at this level (i.e., having exactly the required tags for this depth) are added.&lt;/li&gt;
&lt;li&gt;If links remain, the voting process begins:
&lt;ul class="org-ul"&gt;
&lt;li&gt;Each remaining link votes for the tag it would like to see added next.&lt;/li&gt;
&lt;li&gt;The tag with the most votes is chosen.&lt;/li&gt;
&lt;li&gt;A new list of links that voted for this tag is created.&lt;/li&gt;
&lt;li&gt;The function calls itself with this list and the chosen tag, building the subtree.&lt;/li&gt;
&lt;li&gt;Once processed, those links are removed, and another voting round occurs if any links remain.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;

&lt;li&gt;Exporting the Tree:
&lt;ul class="org-ul"&gt;
&lt;li&gt;Once fully built, the tree is written back into an Org-mode file.&lt;/li&gt;
&lt;li&gt;Done!&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="org2114e78"&gt;The Result&lt;/h2&gt;
&lt;div id="outline-container-org2114e78" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org2114e78"&gt;
&lt;p&gt;
The output file now contains a &lt;b&gt;hierarchically structured and sorted&lt;/b&gt;  list of tags:
&lt;/p&gt;

&lt;ul class="org-ul"&gt;
&lt;li&gt;The most &lt;b&gt;frequent&lt;/b&gt;  tags appear first.&lt;/li&gt;
&lt;li&gt;If two tags have the same frequency, they are sorted &lt;b&gt;alphabetically&lt;/b&gt; .&lt;/li&gt;
&lt;li&gt;&lt;b&gt;All links&lt;/b&gt;  are included in the tree.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;No duplicate links&lt;/b&gt;  exist.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
This gives me a &lt;b&gt;link tree that is highly usable&lt;/b&gt;. While it may not be the &lt;b&gt;perfect&lt;/b&gt; tree I would create manually, it's &lt;b&gt;close enough&lt;/b&gt;. And the best part? There's still plenty of room for &lt;b&gt;optimization&lt;/b&gt;  in the algorithm.
&lt;/p&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="orgb77e32b"&gt;&lt;b&gt;Tweaking the Voting&lt;/b&gt;&lt;/h3&gt;
&lt;div id="outline-container-orgb77e32b" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-orgb77e32b"&gt;
&lt;p&gt;
Anyone interested in voting systems will have realized that there are dozens, if not hundreds, of different voting methods, each leading to slightly different results and optimized for various goals (fixed number of seats, weighting by stock share, minimizing the tags traveled by horse to the capital, etc.).
&lt;/p&gt;

&lt;p&gt;
This also applies to the voting in this algorithm. Currently, every link votes for every tag that benefits it in some way with one vote. However, other variants could also be considered:
&lt;/p&gt;

&lt;ul class="org-ul"&gt;
&lt;li&gt;If a link sees 3 possible trees for Tag A and 2 possible trees for Tag B, it could vote with 3 and 2 votes for the respective tags.&lt;/li&gt;
&lt;li&gt;The votes could be weighted based on whether a tag is immediately needed at this level or possibly further down the tree.&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Overall, I am already very satisfied with the results. My repository with the current state of the tool can be found &lt;a href="https://codeberg.org/dr.ops/tagwood"&gt;(here)&lt;/a&gt;.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description><category>emacs</category><category>orgmode</category><category>python</category><guid>https://plaindrops.de/blog/2025/tagwood/</guid><pubDate>Tue, 04 Mar 2025 09:00:00 GMT</pubDate></item><item><title>Writing Lisp Code with ChatGPT</title><link>https://plaindrops.de/blog/2024/CodingLispWithChatGPT/</link><dc:creator>Andy Drop</dc:creator><description>&lt;p&gt;
I am currently organizing a visit to a major festival, with over 175 bands playing over 4 days at around a dozen different venues scattered across the city. It's quite a logistical challenge. Which bands do I want to see, and do they play with enough time in between to get from Location A to Hall B?
&lt;/p&gt;
&lt;!-- TEASER_END --&gt;
&lt;p&gt;
So, I copied all the data from the organizer's website into an Org document and generated an overview. In Org, it looks like this:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;* Bands  
   :PROPERTIES:
   :COLUMNS: %ITEM %Ort %Datum %Uhrzeit %Link1 %Link2 %Genre
   :END:

#+BEGIN: columnview :id local :skip-empty-rows t
| ITEM             | Ort                     |      Datum | Uhrzeit | Link1 | Link2 | Genre |
|------------------+-------------------------+------------+---------+-------+-------+-------|
| 12 Illusions (D) | Moritzbastei            | 17.05.2024 |   21.00 | [[https://www.youtube.com/watch?v=MOPkUBQbCzA][Song1]] | [[https://www.youtube.com/watch?v=_CUVz7neaRM][Song2]] | o     |
| A Projection (S) | Volkspalast Kuppelhalle | 19.05.2024 |   17.40 | [[https://www.youtube.com/watch?v=W7CndC-CQrw][Song1]] | [[https://www.youtube.com/watch?v=D1C5KpP3Hic][Song2]] | o     |
#+END:   

** 12 Illusions (D)
   :PROPERTIES:
   :Datum: 17.05.2024
   :Uhrzeit: 21.00
   :Ort: Moritzbastei
   :Adresse: Universitätsstraße 9
   :Strassenbahn: 9 (Roßplatz)
   :Strassenbahn+: 8, 9, 11, 14, 16, 32 (Wilhelm-Leuschner-Platz)
   :Bus: 412 (Roßplatz)
   :Bus+: N8 (Roßplatz)
   :S-Bahn: S1, S2, S3, S4, S5, S5X, S6 (Wilhelm-Leuscher-Platz)
   :Link1: [[https://www.youtube.com/watch?v=MOPkUBQbCzA][Song1]]
   :Link2: [[https://www.youtube.com/watch?v=_CUVz7neaRM][Song2]]
   :Genre: o 
   :END:

12 ILLUSIONS is a newly-launched German dark electro pop band.

** A Projection (S)
   :PROPERTIES:
   :Datum: 19.05.2024
   :Ort: Volkspalast Kuppelhalle
   :Adresse: Messehalle 16 / Puschstraße 10
   :Strassenbahn: 16 (An den Tierkliniken)
   :Link1: [[https://www.youtube.com/watch?v=W7CndC-CQrw][Song1]]
   :Link2: [[https://www.youtube.com/watch?v=D1C5KpP3Hic][Song2]]
   :Genre: o 
   :END: 
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
The table at the top is my overview, and since there are now almost 200 lines in it, it's tedious to scroll to one of these bands in the details section. If the organizer hadn't listed them alphabetically, it would be nearly impossible.
&lt;/p&gt;

&lt;p&gt;
The overview table is generated anew, thanks to Org magic, every time I press C-c C-c on the header line. So, the first column is literally identical to the heading of each band-entry. If this heading contained a link to itself, then the first column would be full of links to the details of the bands.
&lt;/p&gt;

&lt;p&gt;
To generate these links, I have to perform several functions:
&lt;/p&gt;

&lt;ul class="org-ul"&gt;
&lt;li&gt;Generate a custom ID for the heading&lt;/li&gt;
&lt;li&gt;Copy this ID to the clipboard&lt;/li&gt;
&lt;li&gt;Select the heading&lt;/li&gt;
&lt;li&gt;Insert the link&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
and all that nearly 200 times.
&lt;/p&gt;

&lt;p&gt;
It would be nice to have a function at least, that performs these steps, which I can then bind to a key.
&lt;/p&gt;

&lt;p&gt;
A question via social media revealed that while similar things have been created before, they all ended up with slightly different goals. And then I thought, let me see if ChatGPT can solve this problem for me.
&lt;/p&gt;
&lt;h2 class="collapsible" id="org447f236"&gt;The original prompt&lt;/h2&gt;
&lt;div id="outline-container-org447f236" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org447f236"&gt;
&lt;p&gt;
Me: Can you write a emacs lisp function, to link an orgmode Heading at point with its own id, creating one if it does not already exist?
&lt;/p&gt;

&lt;p&gt;
ChatGPT: Certainly! Below is a simple Emacs Lisp function that links an Org mode heading at point with its own ID, creating one if it does not already exist:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;defun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;link-heading-with-id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;"Link an Org mode heading at point with its own ID, creating one if it does not already exist."&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;interactive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;org-back-to-heading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nf"&gt;heading&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;nth&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;org-heading-components&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;org-entry-get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"CUSTOM_ID"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;progn&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"id-"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;md5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;org-set-property&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"CUSTOM_ID"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"[[#%s][%s]]"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
Not bad, for a first shot. The function first moves the cursor to the beginning of the current heading, then retrieves the heading text and its existing ID, if it has one. If the heading does not have an ID, it generates one using the &lt;code&gt;md5&lt;/code&gt;  hash of the heading text. Finally, it inserts a link to the heading with its ID.
&lt;/p&gt;

&lt;p&gt;
Unfortunally the cursor is moved to the beginning of the Heading, and so it is inserting the new Link before the ** Heading, making it no longer a Heading, But maybe ChatGPF can correct that.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="orgd399150"&gt;Can you alter it, so it replaces the original Heading?&lt;/h2&gt;
&lt;div id="outline-container-orgd399150" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-orgd399150"&gt;
&lt;p&gt;
ChatGPT: Certainly! Here's the modified function that replaces the original heading with the linked version:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;defun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;link-heading-with-id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;"Replace an Org mode heading at point with a linked version using its own ID, creating one if it does not already exist."&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;interactive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;org-back-to-heading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nf"&gt;heading-start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;point&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;heading-end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;line-end-position&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;heading&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;nth&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;org-heading-components&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;org-entry-get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"CUSTOM_ID"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;progn&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"id-"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;md5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;org-set-property&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"CUSTOM_ID"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;delete-region&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;heading-start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;heading-end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"* [[#%s][%s]]"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
This version of the function deletes the original heading and inserts the linked version in its place. But it still has a problem, that you can see in the last line. It always inserts a level-1 Heading (it prepends one asterisk, fix). Correct yourself ChatGPT.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="org5c0e409"&gt;Alter it, so that it preserves the Heading-Level&lt;/h2&gt;
&lt;div id="outline-container-org5c0e409" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org5c0e409"&gt;
&lt;p&gt;
ChatGPT: Sure! Here's the modified function that preserves the heading level while replacing the original heading with the linked version:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;defun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;link-heading-with-id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;"Replace an Org mode heading at point&lt;/span&gt;
&lt;span class="s"&gt;   with a linked version using its own ID,&lt;/span&gt;
&lt;span class="s"&gt;   preserving the heading level&lt;/span&gt;
&lt;span class="s"&gt;   and creating one if it does not already exist."&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;interactive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;org-back-to-heading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nf"&gt;heading-level&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;org-outline-level&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;heading-start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;point&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;heading-end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;line-end-position&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;heading&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;nth&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;org-heading-components&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;org-entry-get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"CUSTOM_ID"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;progn&lt;/span&gt;
&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"id-"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;md5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;org-set-property&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"CUSTOM_ID"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;delete-region&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;heading-start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;heading-end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"%s [[#%s][%s]]"&lt;/span&gt;
&lt;span class="w"&gt;                            &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;make-string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;heading-level&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;?*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;                            &lt;/span&gt;&lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
This version of the function first retrieves the heading level using &lt;code&gt;org-outline-level&lt;/code&gt; . Then, it deletes the original heading and inserts the linked version with the same heading level. I tried it. and it worked as intended
&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;* Bands  
   :PROPERTIES:
   :COLUMNS: %ITEM %Ort %Datum %Uhrzeit %Link1 %Link2 %Genre
   :END:

#+BEGIN: columnview :id local :skip-empty-rows t
| ITEM                                                       | Ort          |      Datum | Uhrzeit | Link1 | Link2 | Genre |
|------------------------------------------------------------+--------------+------------+---------+-------+-------+-------|
| [[#id-e9884ccd6b1210ce39f04bc2eb7f108a][12 Illusions (D)]] | Moritzbastei | 17.05.2024 |   21.00 | Song1 | Song2 | o     |
#+END:   

** [[#id-e9884ccd6b1210ce39f04bc2eb7f108a][12 Illusions (D)]]
   :PROPERTIES:
   :Datum: 17.05.2024
   :Uhrzeit: 21.00
   :Ort: Moritzbastei
   :Adresse: Universitätsstraße 9
   :Strassenbahn: 9 (Roßplatz)
   :Strassenbahn+: 8, 9, 11, 14, 16, 32 (Wilhelm-Leuschner-Platz)
   :Bus: 412 (Roßplatz)
   :Bus+: N8 (Roßplatz)
   :S-Bahn: S1, S2, S3, S4, S5, S5X, S6 (Wilhelm-Leuscher-Platz)
   :Link1: [[https://www.youtube.com/watch?v=MOPkUBQbCzA][Song1]]
   :Link2: [[https://www.youtube.com/watch?v=_CUVz7neaRM][Song2]]
   :Genre: o
   :CUSTOM_ID: id-e9884ccd6b1210ce39f04bc2eb7f108a
   :END:

12 ILLUSIONS is a newly-launched German dark electro pop band.
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="org089b1e0"&gt;It works&lt;/h2&gt;
&lt;div id="outline-container-org089b1e0" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org089b1e0"&gt;
&lt;p&gt;
Only thing that needs to be done is copying it to the Config and binding it to a key
Oh, and ChatGPT can also do that
&lt;/p&gt;

&lt;p&gt;
Me: Please make a keybinding that binds M-. to this function
&lt;/p&gt;

&lt;p&gt;
ChatGPT:
&lt;/p&gt;

&lt;p&gt;
Sure! You can bind the &lt;code&gt;link-heading-with-id&lt;/code&gt; function to a keybinding of your choice, such as &lt;code&gt;M-.&lt;/code&gt; . Here's how you can do it:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;global-set-key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;kbd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"M-."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;'link-heading-with-id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description><category>chatgpt</category><category>emacs</category><category>llm</category><category>orgmode</category><guid>https://plaindrops.de/blog/2024/CodingLispWithChatGPT/</guid><pubDate>Thu, 09 May 2024 08:00:00 GMT</pubDate></item><item><title>Projekt Medusa: Denote</title><link>https://plaindrops.de/blog/2024/MedusaDenote/</link><dc:creator>Andy Drop</dc:creator><description>&lt;p&gt;
Whoever has already looked &lt;a href="https://plaindrops.de/page/project/dremacs/"&gt;through my projects&lt;/a&gt; will find that there is a project &lt;i&gt;Medusa&lt;/i&gt; that I have set up for myself. In Emacs, there are functions that I only need very rarely, and then I often don't have the necessary command in mind. It is then quite helpful to have a hydra for this situation, and the project under which I combine all these hydras is called Medusa for me. Recently, I wanted to create a hydra for Denote, and I found that there were a few problems.
&lt;/p&gt;
&lt;!-- TEASER_END --&gt;
&lt;p&gt;
In general, I handle the hydras like this: I have two thumb buttons on my keyboard with which I control the hydras. On the left thumb is a rather general hydra that is intended for all functions that are not only needed in a specific mode. Here, you can imagine that the functions, that you normally reach with the prefix CTRL-x.
&lt;/p&gt;

&lt;p&gt;
On the right thumb is a kind of context menu, i.e. the hydra that belongs to the respective mode I am currently in. You can imagine that there are all the functions that are accessible via CTRL-c as a prefix. Me treating the whole thing like a context menu, can also be seen in the fact that I have these hydras lying on the right mouse button at the same time.
&lt;/p&gt;
&lt;h2 class="collapsible" id="org3cc7183"&gt;No Mode, no gain&lt;/h2&gt;
&lt;div id="outline-container-org3cc7183" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org3cc7183"&gt;
&lt;p&gt;
And here the problem already begins. &lt;a href="https://protesilaos.com/emacs/denote"&gt;Denote&lt;/a&gt; is an application that provides many commands to create and link loosely written notes with each other. However, since these notes can be written in all possible formats, the respective major mode of the format always applies. I write this blog, for example, in Org-Mode, which means that the major mode is not Denote but Org-Mode at the moment. The Package Major Mode Hydra therefore does not work.
&lt;/p&gt;

&lt;p&gt;
However, Denote is also not a minor mode that can be turned on or off arbitrarily in all kinds of documents. A document is only a Denote document if it is located in a certain directory (&lt;a href="https://protesilaos.com/emacs/denote#h:15719799-a5ff-4e9a-9f10-4ca03ef8f6c5"&gt;silo&lt;/a&gt;) and follows a naming convention. And since Denote is not a minor mode, it also has no own keymap. But Emacs would not be Emacs if you couldn't do something about it.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="org25f9739"&gt;We Build Ourselves a Minor Mode&lt;/h2&gt;
&lt;div id="outline-container-org25f9739" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org25f9739"&gt;
&lt;p&gt;
It would be good if Denote had a minor mode that would be active whenever the active document is in a Denote silo. Since a silo is always also a directory, Emacs has a tool on board: directory-local variables.
&lt;/p&gt;

&lt;p&gt;
The manual says:
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
The usual way to define directory-local variables is to place a file named .dir-locals.el in a directory. When Emacs opens a file in that directory or one of its subdirectories, the directory-local variables specified in .dir-locals.el are applied as if they were defined as file-local variables for that file. Emacs searches for .dir-locals.el, starting in the directory of the opened file, and moving upwards in the directory tree.
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;
My file &lt;code&gt;.dir-locals.el&lt;/code&gt; is located in the top directory of my silo, and looks like this:
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nf"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nf"&gt;denote-mode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;t&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
This line ensures that the denote-mode is turned on for all files in this directory. This is a minor mode that Denote does not come with out of the box, but that we have to create ourselves first. This happens in the corresponding part of my Emacs configuration.
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;define-minor-mode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-mode&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;"Denote is a simple note-taking tool for Emacs."&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;:lighter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;" Note"&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;:keymap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;
&lt;span class="w"&gt;                   &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;make-sparse-keymap&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;define-key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;kbd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"C-l"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;'denote-link-or-create&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;define-key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;kbd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"C-n"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;'denote-link-after-creating&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;define-key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;kbd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;f6&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;interactive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;find-file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"~/wiki"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
&lt;code&gt;~:lighter&lt;/code&gt; specifies what is written in the mode line when the minor mode is active, and &lt;code&gt;:keymap&lt;/code&gt; specifies which keymap should be used. In this case, an empty keymap is created using &lt;code&gt;make-sparse-keymap&lt;/code&gt;, and filled with the most common commands I need. I probably could have left out this initial filling, since I'm going to do the final keybindings anyway, but I didn't find an example where an empty keymap was created.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="orgae18526"&gt;The Actual Hydra&lt;/h2&gt;
&lt;div id="outline-container-orgae18526" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-orgae18526"&gt;
&lt;p&gt;
I then equip my freshly created keymap with the only important keys. &lt;code&gt;&amp;lt;menu&amp;gt;&lt;/code&gt; is the key code that my right thumb button sends.
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;define-key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-mode-map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;kbd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;menu&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="ss"&gt;'medusa/denote/body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;define-key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-mode-map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;kbd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;mouse-3&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="ss"&gt;'medusa/denote/body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
When I click the right mouse button in a Denote silo, the following hydra appears:
&lt;/p&gt;

&lt;p&gt;
&lt;img src="https://plaindrops.de/images/MedusaDenote.png" alt="nil"&gt;
&lt;/p&gt;

&lt;p&gt;
This is generated by the following code. I use the slightly shorter and nicer syntax that the &lt;code&gt;Pretty Hydra&lt;/code&gt; package provides me with.
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;pretty-hydra-define&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;medusa/denote&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;:color&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;blue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;:quit-key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;escape&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;:title&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Denote"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Create"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"n"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"_n_ew note"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"t"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"other _t_ype"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"d"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-date&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;"other _d_ate"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"s"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-subdirectory&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;"other _s_ubdir"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"T"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-template&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;"with _T_emplate"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"S"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-signature&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;"with _S_ignature"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="s"&gt;"Link"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"l"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-link-or-create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"_l_ink"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"L"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-link-or-create-with-command&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"_L_ink with command"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"h"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-org-extras-link-to-heading&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;"specific _h_eader"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"r"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-add-links&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"by _r_egexp"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"d"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-add-links&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"by _d_ired"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"b"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-backlinks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"_b_acklinks"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="s"&gt;"Rename"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RF"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-rename-file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Rename File"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FT"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-change-file-type-and-front-matter&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;"only FileType"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"UF"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-rename-file-using-front-matter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"use Frontmatter"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="s"&gt;"Dyn. Block"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DL"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-org-extras-dblock-insert-links&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"dyn. Links"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DB"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-org-extras-dblock-insert-backlinks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"dyn. Backlinks"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="s"&gt;"Convert links"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CF"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-org-extras-convert-links-to-file-type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"to File Type"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CD"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;denote-org-extras-convert-links-to-denote-type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"to Denote Type"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;"Other"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"?"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"denote"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Help"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;menu&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;major-mode-hydra&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Major Mode Hydra"&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description><category>denote</category><category>emacs</category><category>hydra</category><category>medusa</category><guid>https://plaindrops.de/blog/2024/MedusaDenote/</guid><pubDate>Fri, 03 May 2024 08:00:00 GMT</pubDate></item><item><title>Keymacs, a program to generate Emacs keybindings </title><link>https://plaindrops.de/blog/2024/keymacs/</link><dc:creator>Andy Drop</dc:creator><description>&lt;p&gt;
Apparently, there are a lot of Emacs purists in the world who, over the years, have learned to type such complex key sequences as C-x r t M-. C-c C-p fluently. I'm not one of them. And when I tried to figure out how to customize it for myself, the web forums were full of comments saying it wasn't a good idea.
&lt;/p&gt;
&lt;!-- TEASER_END --&gt;
&lt;p&gt;
Essentially, for the following reasons:
&lt;/p&gt;

&lt;ol class="org-ol"&gt;
&lt;li&gt;&lt;b&gt;Portability:&lt;/b&gt; If you heavily customize your Emacs key bindings, you may have trouble using Emacs on another system where your customizations are not available. This could be problematic if you frequently switch between different computers or if you need to use Emacs on a remote server.&lt;/li&gt;

&lt;li&gt;&lt;b&gt;Learning curve:&lt;/b&gt; Emacs already has a steep learning curve for beginners, and heavily customizing the key bindings can make it even more difficult for others to understand your configuration. This could be an issue if you collaborate with others or need to share your configuration with someone else.&lt;/li&gt;

&lt;li&gt;&lt;b&gt;Conflicts:&lt;/b&gt; If you're not careful, heavily customized key bindings can lead to conflicts between different packages or modes in Emacs. This can result in unexpected behavior and make it more difficult to diagnose and fix problems.&lt;/li&gt;

&lt;li&gt;&lt;b&gt;Dependency on customizations:&lt;/b&gt; If you become too reliant on your individual key bindings, you may find it difficult to use Emacs without them. This could be an issue if you need to work on a system where you can't use your custom configuration.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
However, I never have to share my &lt;a href="https://plaindrops.de/page/project/Emacs-Config/"&gt;Emacs configuration&lt;/a&gt; with other people, or use Emacs anywhere else than on my two computers. So points 1 and 4 are already out of the way. As for the learning curve, I'm not planning to come up with even more complicated key combinations. I just want to be able to continue working with what has been burned into my memory for decades. So point 2 is also taken care of.
&lt;/p&gt;

&lt;p&gt;
That leaves point 3, and it's true: If you're not careful, heavily customized key bindings can lead to conflicts between different packages or modes in Emacs.
&lt;/p&gt;

&lt;p&gt;
I've avoided this so far by keeping track of the customizations I've made in nice tables (thanks to Org-Mode). This approach is of course quite prone to errors. The tables always have to be consistent with the keybindings in dozens of places in the config. It takes a lot of discipline, and it becomes difficult to just try something out.
&lt;/p&gt;

&lt;p&gt;
It got a bit better when I started to consolidate all the keybindings in a single file. This file is loaded at the end of the init.el, and keybindings are not made anywhere else. This worked for a long time. No more tables. The truth is in the code. Unfortunately, it wasn't that easy to search the code for potential conflicts. You can't just change the sorting in the code from "Keymap Name" to "Used Key" like you could with the tables.
&lt;/p&gt;

&lt;p&gt;
So I sat down and wrote a tool in Python where I can manage my desired keybindings in Org tables again, and the tool automatically generates the desired keybindings from that. It's called
&lt;/p&gt;
&lt;h2 class="collapsible" id="orgbd0605a"&gt;Keymacs&lt;/h2&gt;
&lt;div id="outline-container-orgbd0605a" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-orgbd0605a"&gt;
&lt;p&gt;
The program is quite simple. It goes through a file (default: keymap.org in the current directory), collects all the table rows, and assumes that these are descriptions of keybindings. Header rows and separator rows are ignored, as well as almost all other surrounding text. So you can also describe what you had in mind for the individual bindings in the file.
&lt;/p&gt;

&lt;p&gt;
There are two slightly different tables
&lt;/p&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="org003ad8c"&gt;The explicit table&lt;/h3&gt;
&lt;div id="outline-container-org003ad8c" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-org003ad8c"&gt;
&lt;table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"&gt;


&lt;colgroup&gt;
&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th scope="col" class="org-left"&gt;Key&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Mode&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Ctrl&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Super&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Meta&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Shift&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Function&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Remark&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="org-left"&gt;c&lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-mode&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;'treemacs-copy-file&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;c&lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-node-visit&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;'treemacs-visit-node-close-treemacs&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;c&lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-toggle&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;'treemacs-indicate-top-scroll-mode&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;d&lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-copy&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;'treemacs-paste-dir-at-point-to-minibuffer&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;l&lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-mode&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-copy-map&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;p&lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-copy&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;'treemacs-copy-project-path-at-point&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;r&lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-copy&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;'treemacs-copy-relative-path-at-point&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;n&lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-mode&lt;/td&gt;
&lt;td class="org-left"&gt;X&lt;/td&gt;
&lt;td class="org-left"&gt;X&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;'treemacs-create-dir&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;n&lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-mode&lt;/td&gt;
&lt;td class="org-left"&gt;X&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;'treemacs-create-file&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;
I've picked Treemacs as an example here, which shows a few things quite well. Treemacs has the peculiarity that I don't have to make any inputs in the window. So there's no reason not to just use letters without constantly having my little finger on the Ctrl key. First, the first 3 lines:
&lt;/p&gt;

&lt;table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"&gt;


&lt;colgroup&gt;
&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th scope="col" class="org-left"&gt;Key&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Mode&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Ctrl&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Super&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Meta&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Shift&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Function&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Remark&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="org-left"&gt;c&lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-mode&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;'treemacs-copy-file&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;c&lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-node-visit&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;'treemacs-visit-node-close-treemacs&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;c&lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-toggle&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;'treemacs-indicate-top-scroll-mode&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;
There are 3 different places where I can simply press &lt;code&gt;c&lt;/code&gt;, but they are not in conflict with each other because they are in different keymaps. To get the name of the keymap, the program simply appends &lt;code&gt;-map&lt;/code&gt; to the mode.
&lt;/p&gt;

&lt;p&gt;
But wait, there's no &lt;code&gt;treemacs-toggle&lt;/code&gt; mode? That's right, but there is a keymap for it and a prefix that it's bound to. I'll show that with the &lt;code&gt;treemacs-copy-map&lt;/code&gt;:
&lt;/p&gt;

&lt;table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"&gt;


&lt;colgroup&gt;
&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th scope="col" class="org-left"&gt;Key&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Mode&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Ctrl&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Super&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Meta&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Shift&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Function&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Remark&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="org-left"&gt;l&lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-mode&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-copy-map&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;d&lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-copy&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;'treemacs-paste-dir-at-point-to-minibuffer&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;p&lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-copy&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;'treemacs-copy-project-path-at-point&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;r&lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-copy&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;'treemacs-copy-relative-path-at-point&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;a&lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-copy&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;'treemacs-copy-absolute-path-at-point&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;
This map is originally called &lt;code&gt;treemacs-copy-map&lt;/code&gt; even though the original function in it just copies the current file (and I've mapped that to a shorter &lt;code&gt;c&lt;/code&gt;). All the others just put various links in the clipboard, so I've chosen &lt;code&gt;l&lt;/code&gt; as the key to get into the &lt;code&gt;treemacs-copy-map&lt;/code&gt;, and the following key then selects what kind of link I want (absolute, relative or to the project root?) &lt;code&gt;l a&lt;/code&gt; gives me the link as an absolute path.
&lt;/p&gt;

&lt;p&gt;
And of course, I can still use &lt;code&gt;Ctrl&lt;/code&gt; combinations if I want to. For example, many programs use &lt;code&gt;Ctrl-n&lt;/code&gt; to create a new file, a new object, or something else new. Why should I ignore that? So:
&lt;/p&gt;

&lt;table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"&gt;


&lt;colgroup&gt;
&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th scope="col" class="org-left"&gt;Key&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Mode&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Ctrl&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Super&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Meta&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Shift&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Function&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Remark&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="org-left"&gt;n&lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-mode&lt;/td&gt;
&lt;td class="org-left"&gt;X&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;'treemacs-create-file&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;n&lt;/td&gt;
&lt;td class="org-left"&gt;treemacs-mode&lt;/td&gt;
&lt;td class="org-left"&gt;X&lt;/td&gt;
&lt;td class="org-left"&gt;X&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;'treemacs-create-dir&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;
So I can create a new file with &lt;code&gt;Ctrl-n&lt;/code&gt; and a new directory with &lt;code&gt;Ctrl-Super-n&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
However, the common &lt;code&gt;Ctrl&lt;/code&gt; combinations are of course useful in many different modes, and you have to be a little careful that the keybindings don't interfere with each other, especially when minor-modes come into play. For that, you'd better use:
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="org832d3fc"&gt;The implicit table&lt;/h3&gt;
&lt;div id="outline-container-org832d3fc" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-org832d3fc"&gt;
&lt;p&gt;
At first glance, the table looks the same, but the Key column on the left is missing.
&lt;/p&gt;

&lt;table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides"&gt;


&lt;colgroup&gt;
&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;

&lt;col class="org-left"&gt;
&lt;/colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th scope="col" class="org-left"&gt;Mode&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Ctrl&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Super&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Meta&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Shift&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Function&lt;/th&gt;
&lt;th scope="col" class="org-left"&gt;Remark&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="org-left"&gt;Global&lt;/td&gt;
&lt;td class="org-left"&gt;X&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;'org-insert-link-global&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;org-mode&lt;/td&gt;
&lt;td class="org-left"&gt;X&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;'org-insert-link&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;org-mode&lt;/td&gt;
&lt;td class="org-left"&gt;X&lt;/td&gt;
&lt;td class="org-left"&gt;X&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;'org-super-links-insert-link&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td class="org-left"&gt;org-mode&lt;/td&gt;
&lt;td class="org-left"&gt;X&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;td class="org-left"&gt;X&lt;/td&gt;
&lt;td class="org-left"&gt;'org-super-links-link&lt;/td&gt;
&lt;td class="org-left"&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;
But how does &lt;code&gt;keymacs&lt;/code&gt; know which key to bind to? I mentioned at the beginning that &lt;code&gt;keymacs&lt;/code&gt; ignores header rows and separator rows, as well as &lt;b&gt;almost&lt;/b&gt; all other surrounding text. Now here's the reason for the "almost", and for that we need to look at the Org-mode:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;** N New
 | Mode       | Ctrl | Super | Meta | Shift | Function                 | Remark |
 |------------+------+-------+------+-------+--------------------------+--------|
 | Global     | X    |       |      |       | 'find-file               |        |
 | org-mode   | X    |       |      |       | 'find-file               |        |
 | dired-mode | X    |       |      |       | 'dired-create-empty-file |        |
 | dired-mode | X    | X     |      |       | 'dired-create-directory  |        |
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
&lt;code&gt;Keymacs&lt;/code&gt; reads the first word from all Org header rows (here 'N') and uses it for the subsequent implicit tables. A new header sets a different key, e.g.
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;** F9 Treemacs - a tree layout file explorer for Emacs
 | Mode   | Ctrl | Super | Meta | Shift | Function                | Remark |
 |--------+------+-------+------+-------+-------------------------+--------|
 | Global |      |       |      |       | 'treemacs-select-window |        |
 | Global |      |       |      | X     | 'treemacs-find-file     |        |
 | Global | X    |       |      |       | 'treemacs-find-tag      |        |
 |        |      |       |      |       |                         |        |
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
Except for the first word, &lt;code&gt;keymacs&lt;/code&gt; doesn't care about anything else. Incidentally, you can also see here that the global-map is filled with "Global" (with a capital G). The order of the columns must be correct, the headers are only for the reader and are ignored.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="orgbc1ce04"&gt;The program&lt;/h2&gt;
&lt;div id="outline-container-orgbc1ce04" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-orgbc1ce04"&gt;
&lt;p&gt;
I originally wrote this whole thing to solve my own problem, and later also to test the entire development process using Hatch. That's why the whole thing is also available for (test) PyPi for download. Since I want to internalize this whole Python workflow, I will continue to work on this tool, even though it already solves all my problems. But the code is ugly and so far only has a "happy path" without error handling.
&lt;/p&gt;

&lt;p&gt;
The source code is &lt;a href="https://codeberg.org/dr.ops/keymacs"&gt;here&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
If you just want to install it, I recommend using &lt;code&gt;pipx&lt;/code&gt;. Then it's as simple as:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;pipx install -i https://test.pypi.org/simple/ keymacs
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
The program only reads the keymap.org file and then writes a keymap.el that you can include at the end of your init.el
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;(load (concat user-emacs-directory "config.el"))
;;(load (concat user-emacs-directory "sanekeys.el"))
(load (concat user-emacs-directory "medusa.el"))
(org-babel-load-file (concat user-emacs-directory "elgato.org"))
(org-babel-load-file (concat user-emacs-directory "skeletons.org"))
(load (concat user-emacs-directory "keymap.el"))

(setq custom-file (concat user-emacs-directory "custom.el"))
;; (load (concat user-emacs-directory "custom.el"))
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description><category>emacs</category><category>keybindings</category><guid>https://plaindrops.de/blog/2024/keymacs/</guid><pubDate>Tue, 23 Apr 2024 08:00:00 GMT</pubDate></item><item><title>Just quickly print something in Emacs</title><link>https://plaindrops.de/blog/2024/PrintingInEmacs/</link><dc:creator>Andy Drop</dc:creator><description>&lt;p&gt;
In Emacs, there are several ways to generate neat prints. Most of them end up creating PDFs. But if you just want to quickly have a printout of the buffer to work with a pencil and highlighter, that can sometimes be a problem. I spent an evening trying to solve that, and eventually succeeded. To remember it, I wrote this blog post.
&lt;/p&gt;
&lt;!-- TEASER_END --&gt;
&lt;p&gt;
Basically, there's the command &lt;code&gt;print-buffer&lt;/code&gt;, which I habitually invoke with &lt;i&gt;CTRL-p&lt;/i&gt;. I expect paper to come out of the printer, containing unformatted text, just like what I see on the screen in the buffer.
&lt;/p&gt;

&lt;p&gt;
Unfortunately, that didn't work for me at all. Emacs uses the Linux command line command &lt;code&gt;lpr&lt;/code&gt; for this kind of printouts, and it quickly became clear that it wasn't doing any good on the command line either. Every attempt to print something with it, ended with a message saying that the &lt;code&gt;lpr&lt;/code&gt; daemon wasn't running. Every attempt to start it failed. At some point, it dawned on me that maybe &lt;code&gt;lpr&lt;/code&gt; is just too old as a printing tool.
&lt;/p&gt;
&lt;h2 class="collapsible" id="org51d875b"&gt;Back to the Future&lt;/h2&gt;
&lt;div id="outline-container-org51d875b" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org51d875b"&gt;
&lt;p&gt;
&lt;code&gt;lpr&lt;/code&gt; is indeed an older command, stemming from the times when printers were often directly connected to Unix systems. However, it came to pass that the "Common Unix Printing System" (CUPS) was developed, providing modern print management on Unix systems. And a little web search revealed that it comes with its own command line command, &lt;code&gt;lp&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
The syntax of the two commands varies slightly. &lt;code&gt;lpr&lt;/code&gt; usually simply accepts the filename I want to print, while &lt;code&gt;lp&lt;/code&gt; accepts a range of options that allow me to control various aspects of the print job, such as the number of copies, the printer, the paper format, etc.
&lt;/p&gt;

&lt;p&gt;
Emacs kindly provides the option to configure the command it uses under the hood. So, instead of &lt;code&gt;lpr&lt;/code&gt;, we say we'd rather use &lt;code&gt;lp&lt;/code&gt;:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;lpr-command&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"lp"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
Since &lt;code&gt;lp&lt;/code&gt; and &lt;code&gt;lpr&lt;/code&gt; pass different parameters on the command line, it also doesn't make sense to continue using the &lt;code&gt;lpr&lt;/code&gt; standard switches for &lt;code&gt;lp&lt;/code&gt;. So, we turn them off:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;lpr-add-switches&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
And boom, everything worked as expected. So I persisted it in my &lt;a href="https://plaindrops.de/page/project/Emacs-Config/#org286df2f"&gt;Config&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="org074a0fa"&gt;Conclusion&lt;/h2&gt;
&lt;div id="outline-container-org074a0fa" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org074a0fa"&gt;
&lt;p&gt;
If you're not using an antique Linux system, &lt;code&gt;lpr&lt;/code&gt; doesn't make sense anymore and should be replaced by &lt;code&gt;lp&lt;/code&gt;. In my humble opinion, that would be a good default by now.
&lt;/p&gt;

&lt;p&gt;
By the way, in the configuration, you can also set your own parameters to pass to &lt;code&gt;lp&lt;/code&gt;, which I think will help me achieve double-sided printing as well.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description><category>emacs</category><category>printing</category><guid>https://plaindrops.de/blog/2024/PrintingInEmacs/</guid><pubDate>Fri, 19 Apr 2024 08:00:00 GMT</pubDate></item><item><title>Finance under Control with Ledger (2) - The Emacs ledger mode</title><link>https://plaindrops.de/blog/2020/finance-under-control-2/</link><dc:creator>Andy Drop</dc:creator><description>&lt;p&gt;
In the last part I wrote about how bookings in Ledger work and how
they are written. Because they are just simple text files, you don't
need more than a plain text editor. Choosing Emacs, the work becomes a
little bit easier.
&lt;/p&gt;
&lt;!-- TEASER_END --&gt;

&lt;p&gt;
Well, admittedly, easy is not the right word when it comes to
mathematics, but having your finances under control, and being not
overwhelmed every January from the wave of "unexpected" bookings is a
good feeling. And Emacs helps you with Ledger Mode at simply writing
flawless booking records.
&lt;/p&gt;
&lt;h2 class="collapsible" id="orgb0fcda1"&gt;Automatic accountname completion&lt;/h2&gt;
&lt;div id="outline-container-orgb0fcda1" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-orgb0fcda1"&gt;
&lt;p&gt;
A major source of problems is that the account names (which are
usually within categories) may become very long.
&lt;i&gt;Expenses:Living:Additional costs:Electricity&lt;/i&gt; is a quite ordinary
account name. When you load your ledger file The Ledger Mode reads all
your account names and after that you can add the parts of those
account names by tab completion. In addition to the time saved on
typing, this decreases the chance of typos.
&lt;/p&gt;

&lt;p&gt;
Speaking of typos in account names: Ledger offers the opportunity to
create unknown accounts in a booking on the fly if the don't exist. As
seductive as this option is, you should stay away from it and choose
the exact other way to be your way of working.
&lt;/p&gt;

&lt;p&gt;
With that configuration Ledger refuses to work as soon as an account
you want to book to, was not explicitly set up beforehand.  This
refusal may seem annoying at first, but then Ledger at least gives you
a good hint which account was misspelled. Without this hint you are faced with the
challenge of just having wrong values ​​in this accounts and trying to find the
cause in hundreds of bookings.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="org66d702b"&gt;Aided reality checks.&lt;/h2&gt;
&lt;div id="outline-container-org66d702b" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org66d702b"&gt;
&lt;p&gt;
Another help to ensure that your bookkeeping does not deviate from
reality, is a regular reconciliation of accounts. I do that for my
current account &amp;amp; the credit card based on the bank statements and for
my purse by simply putting the contents of it on the table.
&lt;/p&gt;

&lt;p&gt;
In any case, I get the account balance that my bookkeeping &lt;b&gt;should&lt;/b&gt; also
show. The Reconcile function of the ledger mode asks me for this value
when called, and then gives me a listing of all bookings that I have
not yet matched with reality. Now I can sit down with my bank statement in my
hand and mark all the bookings that I also see in Ledger. During this process I
always see the difference of my confirmed bookings against the reality. As soon as
this difference is 0, the adjustment is done, and the temporary
markings become final. I never have to worry about these finalized bookings again.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="org5e11da9"&gt;Automatic report updates&lt;/h2&gt;
&lt;div id="outline-container-org5e11da9" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org5e11da9"&gt;
&lt;p&gt;
Reality matching is sometimes difficult, especially with cash, because
it presupposes that every cent you may have spend somewhere for some
candy bar somehow gets into the accounts. For this reason, I recommend
to minimize cash payments at the beginning and pay a lot with
plastic. The money you get from the ATM could then be booked with an
general cash account, or split, or split according to your
feelings. Only those who are willing to keep disciplined notes of
their cash spendings will have fun with tracking their cash expenses.
&lt;/p&gt;

&lt;p&gt;
I use a USB voice recorder anyway for small notes and so the cash
accounting works very well. In those cases where it becomes a bit more
work to understand my expenses, it is helpful that Emacs shows me the
register of my expenses in a second window. Its good to see spendings
and income (when I was at the ATM) in my wallet and update immediately
when I add bookings.
&lt;/p&gt;

&lt;p&gt;
Suppose I think that two weeks ago I bought food for 15 Euros at the
chinese food store.  When I type that into my ledger I see immediately
something can't be right, because the final sum of my cash accounts
correspond to what I have in my wallet (and thus the 15 euros were
actually spent) but the time of this spending cannot be correct
because otherwise my wallet must have been temporarily in the negative
numbers, which is simply not possible with cash.
&lt;/p&gt;

&lt;p&gt;
So obviously it was not two, but one week ago, &lt;b&gt;after&lt;/b&gt; I was at the ATM
in between. I can make my booking shift through time and see
immediately in the report whether one Booking may have been possible
or not.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="orgcbeb664"&gt;Automatic cleanup&lt;/h2&gt;
&lt;div id="outline-container-orgcbeb664" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-orgcbeb664"&gt;
&lt;p&gt;
Even if this function is actually nothing stunning, it is tremendously
practical if you don't have to pay attention to where in the file you
write your bookings, or whether you also place all decimal points
below the other. The ledger mode has both functions, legible
formatting and time sorting of booking. I have it even made more
simple for me and call this "make pretty" by  a hook every time I
save my ledger file. So all data is always Formatted for easy reading
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description><category>emacs</category><category>ledger</category><guid>https://plaindrops.de/blog/2020/finance-under-control-2/</guid><pubDate>Fri, 21 Feb 2020 12:00:00 GMT</pubDate></item><item><title>Finance under Control with Ledger (1) - Basics</title><link>https://plaindrops.de/blog/2019/finance-under-control-1/</link><dc:creator>Andy Drop</dc:creator><description>&lt;p&gt;
Who of us does not know that. At the end of the money there is plenty of the month left, and is usually used by the Gasworks and the goldfish breeders' club to collect their annual fee (including the price increase) from your account.
&lt;/p&gt;

&lt;p&gt;
I also had a time when I had to do a lot of financial juggling to live from month to month, even though I had as much money as today. I just did not have under control as well as I now have. The heart of the problem was actually that I almost never knew how much of the money in my account was really free to spend, and what bills would come up in the near future.
&lt;/p&gt;
&lt;!-- TEASER_END --&gt;
&lt;p&gt;
And then I sat down and decided to change that. First with pencil and paper, later with the support of the PC. I have tried various systems, bringing me finally to Ledger. Over the past year, I have been making little tests of how to handle my money, and since there were no major difficulties, I switched to Ledger at the beginning of 2019.
&lt;/p&gt;
&lt;h2 class="collapsible" id="orge0f961b"&gt;What can Ledger do (bookings &amp;amp; transactions)&lt;/h2&gt;
&lt;div id="outline-container-orge0f961b" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-orge0f961b"&gt;
&lt;p&gt;
Actually, ledger can do very few things, but for those it is very flexible, so it can cover a lot of use cases.
&lt;/p&gt;

&lt;ol class="org-ol"&gt;
&lt;li&gt;It reads one or more text files with postings&lt;/li&gt;
&lt;li&gt;It sums up these postings (and distinguishes between the accounts in which they are posted)&lt;/li&gt;
&lt;li&gt;It either displays the complete register, or the balance on the screen&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
One thing that stands out is that Ledger definitely does not write to the postings in my files. &lt;span class="underline"&gt;I&lt;/span&gt; write my postings, and Ledger just evaluates them. It's very fast and precise in that.
&lt;/p&gt;

&lt;p&gt;
An example:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;2019-03-10 gas station
   Gasoline 50.00
   Checking account -50.00
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
What we see here is a transaction. This is the building block that we most often deal with in Ledger. It consists of the head, which indicates, when the transaction took place and who the partner was (here the gas station), as well as a number of postings (these are each a little indented).
Postings are the smallest building block we use in Ledger. A posting identifies an account and an amount added to the account (or subtracted if the amount is negative). Several of these postings form a transaction.
&lt;/p&gt;

&lt;p&gt;
The essential feature of a transaction is that the postings &lt;b&gt;ALWAYS&lt;/b&gt; have to sum up to 0. Otherwise, the transaction is not valid and generates an error, crashing ledger.
&lt;/p&gt;

&lt;p&gt;
Consequently, this means that there must be at least one counter entry in each transaction. A transaction thus always consists of at least two postings, and is therefore commonly called "double entry accounting". Every euro that comes from one account must go in another account.
&lt;/p&gt;

&lt;p&gt;
If I let Ledger evaluate the above example and let me see the balance, it tells me, for example, that the account gas is now 50.00, and my checking account is now 50.00 in debt.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="orgfa85c81"&gt;Accounts&lt;/h2&gt;
&lt;div id="outline-container-orgfa85c81" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-orgfa85c81"&gt;
&lt;p&gt;
"That's great," you may say now, "if I need the 50.00 Euro again, then I'll just book it from the gasoline account, and …". But that's not how it works. The gas station will not like it if you took their money from them back. Even if you could do that in the theory of bookkeeping.
&lt;/p&gt;

&lt;p&gt;
In reality, you use a few categories of accounts, that you then only use for certain types of postings. This is called the standard form (or chart) of accounts, and theoretically can be made by anyone as he feels like. In practice, however, a handful of chart of accounts have proven to be standardized in a way that different companies work with the same chart of accounts.
&lt;/p&gt;

&lt;p&gt;
For me as a private user, a specific chart of accounts has been tried &amp;amp; tested that consists of 6 categories
&lt;/p&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="org8521e22"&gt;Income&lt;/h3&gt;
&lt;div id="outline-container-org8521e22" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-org8521e22"&gt;
&lt;p&gt;
Somewhere the money has to come from, and here we find all the accounts, where the money is almost "created". We remember: If my salary arrives on my checking account, it will need a corresponding conter entry.
Therefore, the posting looks like this
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;2019-03-01 Company Baumeister
   Income:Salary -2000.00
   Credit:Bank 2000.00
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
As my bank account becomes more and more positive, the income are becoming more and more negative. Which also corresponds to the reality. When I get a salary, my company gets a little poorer.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="org8386406"&gt;Expenses&lt;/h3&gt;
&lt;div id="outline-container-org8386406" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-org8386406"&gt;
&lt;p&gt;
The opposite is the case when I spend money
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;2019-03-10 gas station
   Expenses: Gasoline 50.00
   Credit:Bank -50.00
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
If I pay an invoice from my bank account, then the money has to "disappear" somewhere, and it does so only on "expenses" accounts. 
&lt;/p&gt;

&lt;p&gt;
In Ledger one speaks actually not of categories, but only of accounts. Accounts may also contain subaccounts (for example) Spending: Utilities: Gas and Spending: Utilities: Water. If I post something like these with these accounts:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;2019-03-09 Stadtwerke
   Credit:checking  -100.00
   Expenses:Additional costs: Gas 50.00
   Expenses:Additional costs: Water 40.00
   Expenses:Additional costs: 10.00
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
Then you can see that here from the checking account an amount of 100 euros for the Stadtwerke was paid, which comes completely from the account Expenses:Additional costs. Of which 50.00 from the account for gas and 40.00 from the account for water. In addition, the Stadtwerke has charged me a general fee of 10.00, which I can not assign directly to the gas or water, but it is part of the additional costs. Here you can see that a transaction &lt;b&gt;must contain at least&lt;/b&gt; two postings, but it may also be more. They &lt;b&gt;must&lt;/b&gt; only add up to 0.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="org7a19ca4"&gt;Credit&lt;/h3&gt;
&lt;div id="outline-container-org7a19ca4" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-org7a19ca4"&gt;
&lt;p&gt;
It's really easy. This includes all accounts on which there is usually money, ie the checking account, the savings account, the wallet. It's money (or values) that I have. If an account pays interest to me, it is most likely a credit account
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="orgaa18ea5"&gt;Debit&lt;/h3&gt;
&lt;div id="outline-container-orgaa18ea5" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-orgaa18ea5"&gt;
&lt;p&gt;
These are debts I have somewhere. As a rule, I recognize debit accounts by paying interest because somebody has made money available to me here. Typically, these are the house  loans or the credit card.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="org1fc3537"&gt;Compensation&lt;/h3&gt;
&lt;div id="outline-container-org1fc3537" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-org1fc3537"&gt;
&lt;p&gt;
Compensation accounts are accounts that should not exist in a perfect accounting world. Unfortunately, the world is not perfect, and so I've got two subaccounts for compensations
&lt;/p&gt;

&lt;ol class="org-ol"&gt;
&lt;li&gt;&lt;p&gt;
Compensations:debut
&lt;/p&gt;

&lt;p&gt;
I use this account exactly 1 time at the beginning of the bookkeeping, and then &lt;b&gt;never again&lt;/b&gt;. If I start accounting sometime today, my checking account already has money and my credit card is in debt. So I book on my checking account the money that should be on it today, and the counter posting then goes against the account Compensation.
Here, money is actually generated from very thin air. So, to not use this for cheating, I have exactly one posting at the very beginning, and then never again.
&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;
Compensation:lostfound
&lt;/p&gt;

&lt;p&gt;
Since I also manage my cash (ie the wallet), it may sometimes happen that I simply have less money in the wallet than actually should be according to my bookkeeping. Sometimes I lose money in the washing machine, or elsewhere, sometimes money unexpectedly reappears in the lint filter.
For all this there is this account as a counter account to the wallet. The account should be used as seldom as possible, and should be as little as possible off from 0. If this is no longer guaranteed, this is a sure sign of a general problem with discipline whith posting, or with  spending cash.
If I know, for example, that I have spent the night before 50.00 on a pub crawl,  but I somehow 51.00 are missing in my wallet, then I just book 51.00  on the leisure account, and  don't use thelostfond account for the missing 1.00. It is only used when I can no longer reasonably explain the disappearance.
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="org88db010"&gt;Budget&lt;/h3&gt;
&lt;div id="outline-container-org88db010" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-org88db010"&gt;
&lt;p&gt;
Actually, Ledger has a built-in functionality that allows me to manage budgets (money that is reserved for certain expenses). Unfortunately, this is somewhat limited in terms of flexibility. So, using the Budget account and its subaccounts, I'm simulating a method that has worked well for my grandmother to put money aside for later: envelopes.
&lt;/p&gt;

&lt;p&gt;
Whenever my salary arrives I put a little money into each of those envelopes. And then, when the car insurance wants its money, I open this envelope, and it contains exactly the amount that I have to pay as expected.
Of course, I do not fill these envelopes literally. They do not even exist. They are just virtual envelopes, and the budget account is a subaccount of my checking account. The bank does not know this subaccount. From their perspective , I have 300 euros in my checking account. But Ledger can show me in this way that of these 300 euros are already 180 in a virtual envelope labeled car insurance, and I therefore have only 120 euros to spend.
&lt;/p&gt;

&lt;p&gt;
The necessary postings of a budget transaction can sometimes be very confusing, but with a little practice this is possible. I will go into detail later.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="org0e4baf7"&gt;Work easier&lt;/h2&gt;
&lt;div id="outline-container-org0e4baf7" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org0e4baf7"&gt;
&lt;p&gt;
As mentioned earlier, Ledger simply reads the files and evaluates them. At no time does Ledger write anything in one of the files (there is a small exception that you have to explicitly request, and you almost never need)
&lt;/p&gt;

&lt;p&gt;
But it also means that I have to type the complete postings myself by hand, including the matching counter postings. The account names must not contain any typos (which may be exciting for names such as Expenses:Household:Food:Biobox) If I call an account once dirtwater fee and once dirtwater charge, then these are for Ledger two completely different accounts, which then each individually summed up, and never merge
&lt;/p&gt;

&lt;p&gt;
Ledger has some simplifications at hand for this very time-consuming and error-prone typing work:
&lt;/p&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="orga34cc79"&gt;The chart of accounts&lt;/h3&gt;
&lt;div id="outline-container-orga34cc79" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-orga34cc79"&gt;
&lt;p&gt;
Of course, I will eventually mistype an account name over time. And then, before I book money on any account called Expense:Carinsuracne and wonder why there's no change in the real account, it's better if Ledger controls it.
&lt;/p&gt;

&lt;p&gt;
Ledger can be configured to tell it what accounts I want to use, and how the entire chart of accounts (all my accounts and subaccounts) is built. After that I can only use these accounts. Any typos will be mercilessly flagged, and Ledger will refuse to validate my postings until the error is resolved. Thankfully, he tells me exactly where the problem is.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="orgf6179b9"&gt;Aliases&lt;/h3&gt;
&lt;div id="outline-container-orgf6179b9" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-orgf6179b9"&gt;
&lt;p&gt;
An account named Expenses:Household:Groceries:Biobox can be very annoying to type. Therefore, Ledger offers the possibility to give short aliases instead of these word monsters. I then have to go e.g. Just type "Bio" and Ledger knows I mean that account.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="orged499a7"&gt;The empty posting&lt;/h3&gt;
&lt;div id="outline-container-orged499a7" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-orged499a7"&gt;
&lt;p&gt;
Even amounts  could be mistyped quickly, or you can't calculate in your head, what sum an counter posting has to have.
If the Stadtwerke bills me I just want to write this:
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;2019-01-02 Stadtwerke
   Gas 12.34
   Water 56.78
   checking account
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
As you can see, there is no amount in the checking account, and if there is a transaction with &lt;b&gt;exactly one&lt;/b&gt; account with no amount, Ledger simply takes  the amount needed to balance the other postings. In this case, -69.12 will be posted to the checking account (ie 69.12 deducted)
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="org9d75e5d"&gt;The default account&lt;/h3&gt;
&lt;div id="outline-container-org9d75e5d" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-org9d75e5d"&gt;
&lt;p&gt;
Most of us have exactly one checking account, and all bank transactions run through this one account. Because even if you use something as alias as short as "Giro", it can be annoying to write it down for every transaction.
However, Ledger offers the option to make an account have the function of an default account, which is then always accepted when the transaction is not cleared and the account is not already used in the transaction.
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;2019-01-02 Stadtwerke
   Gas 12.34
   Water 56.78
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
is therefore a valid posting record, if previously the checking account has been agreed as the standard account. In this case, the checking account is automatically taken as an counter account and the corresponding amount determined as explained in the section "&lt;a href="https://plaindrops.de/blog/2019/finance-under-control-1/#orged499a7"&gt;empty posting&lt;/a&gt;"
&lt;/p&gt;

&lt;p&gt;
Also
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;2019-01-02 Stadtwerke
   Gas 12.34
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
is now a valid posting, even though the transaction violates the rule that a transaction must consist of at least 2 transactions. The missing posting goes to the previously defined default account
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 class="collapsible" id="org8cd127d"&gt;The Ledger Mode&lt;/h3&gt;
&lt;div id="outline-container-org8cd127d" class="outline-3 collapsme"&gt;
&lt;div class="outline-text-3" id="text-org8cd127d"&gt;
&lt;p&gt;
As you can see, Ledger already has a lot of options built in that make typing easier. For the Emacs environment, there exists even a ledger mode, which further simplifies the input by e.g. proposing suitable posting data, or recurring postings after a few typed letters, or inserting them completely. In addition, it offers quite comfortable functions to create reports, or regularly adjusting the posted data with the reality. The Ledger Mode will be a article of its own.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description><category>emacs</category><category>ledger</category><guid>https://plaindrops.de/blog/2019/finance-under-control-1/</guid><pubDate>Fri, 12 Jul 2019 05:00:00 GMT</pubDate></item><item><title>Medusa -  The mother of all Hydras</title><link>https://plaindrops.de/blog/2019/medusa-mother-of-all-hydras/</link><dc:creator>Andy Drop</dc:creator><description>&lt;figure&gt;&lt;img src="https://plaindrops.de/de/blog/2019/medusa-mother-of-all-hydras/medusa.png%20Medusas%20head"&gt;&lt;/figure&gt; &lt;p&gt;
One of the problems of all text editors is that they actually have to reconcile two different functions, capturing text, and editing of text. That we are seldom aware of how different these two tasks are is also part of the problem. Our mind tends to switch seamlessly between these two tasks.
&lt;/p&gt;

&lt;p&gt;
We write a sentence, and even as we type it, we notice that after the last word it would have been better to have a comma, and that the whole paragraph might have been part of the introduction anyway, maybe as a quotation.
&lt;/p&gt;
&lt;!-- TEASER_END --&gt;

&lt;p&gt;
This way of working makes it necessary to switch between capturing and editing text at any time. Essentially, 3 approaches have prevailed. Common to all of them is that they often find the simple functions on their own keys (Delete, Tab, PageUp, etc …). For the more complicated cases we find:
&lt;/p&gt;

&lt;ol class="org-ol"&gt;
&lt;li&gt;The menu control (eg Word) with the problem that you have to switch between the mouse and keyboard back and forth for mouse operation.&lt;/li&gt;

&lt;li&gt;A multiple assignment of the keys via ALT, CTRL, META, SUPER or HYPER keys. This is the area where Emacs is at home.&lt;/li&gt;

&lt;li&gt;A leader key, which is a key that does not appear in normal text, and therefore serves to switch to edit mode. This is the domain of VIM&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
   
&lt;/p&gt;
&lt;h2 class="collapsible" id="org1f48bee"&gt;Spacemacs and the Leaderkey&lt;/h2&gt;
&lt;div id="outline-container-org1f48bee" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org1f48bee"&gt;
&lt;p&gt;
Just like for me, also for the makers of Spacemacs the idea with the Leaderkey, is the way to go. So they have adopted the concept as far as possible and put it over an existing Emacs as a configuration. The charm is that it does not affect any of the usual features in Emacs, and now both types of operation can coexist. What has unfortunately been lost in my eyes, is the more systematic structure of the functions that Emacs usually brings. The Hydras delivered by Spacemacs (a kind of visual menu guide) rarely seem useful or easy to remember in my head
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="org327be8d"&gt;Thing at point&lt;/h2&gt;
&lt;div id="outline-container-org327be8d" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org327be8d"&gt;
&lt;p&gt;
I get, for example, always the same Hydra when I press the Leaderkey, while you can choose in Emacs countless modes of operation, each requiring completely different ways of interaction.
&lt;/p&gt;

&lt;p&gt;
In a recent blog entry from &lt;a href="https://dfeich.github.io/www/org-mode/emacs/2018/05/10/context-hydra.html"&gt;Derek Feichtinger&lt;/a&gt;, I recently found a very elegant solution that not only can provide different Hydras for the different modes, but is also still able to determine if the cursor is in the very popular &lt;i&gt;Org mode&lt;/i&gt; on an object (such as a link or table), and then call a Hydra specific to that object.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="org0c14077"&gt;Fallback&lt;/h2&gt;
&lt;div id="outline-container-org0c14077" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org0c14077"&gt;
&lt;p&gt;
The elegant thing about this solution is that on the one hand it is very easy to expand, and on the other hand it also offers the possibility to call a standard Hydra if none of the special cases are present.
&lt;/p&gt;

&lt;p&gt;
In the combination of different Hydras this offers unexpected possibilities. For example, my Leaderkey is the &amp;lt;menu&amp;gt; key, which is usually to the right of the space bar, and calls the context menu on Winows. With Linux this had never been a useful feature for me anyway.
&lt;/p&gt;

&lt;p&gt;
In each Hydra, I programmed the &amp;lt;menu&amp;gt; key with the most frequently used function. This allows me to press the menu button twice and - in Org Mode - do the same thing that Ctrl-C Ctrl-C does, while in Ledger Mode a new booking is created instead.
&lt;/p&gt;

&lt;p&gt;
Again, as with the Spacemac solution, all of the built-in Emacs buttons continue to work as normal, I've now integrated all the Hydras that I've created so far into the Medusa project, the sources are &lt;a href="https://codeberg.org/dr.ops/medusa%20"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description><category>emacs</category><category>hydra</category><category>medusa</category><category>orgmode</category><category>project</category><guid>https://plaindrops.de/blog/2019/medusa-mother-of-all-hydras/</guid><pubDate>Tue, 14 May 2019 17:56:29 GMT</pubDate></item><item><title>My perfect typing environment. Finally.</title><link>https://plaindrops.de/blog/2018/de-code/</link><dc:creator>Andy Drop</dc:creator><description>&lt;figure&gt;&lt;img src="https://plaindrops.de/de/blog/2018/de-code/de-code_header.png%20A%20schematic%20drawing%20of%20a%20keyboard%20layout%20with%20some%20of%20the%20keys%20marked%20in%20various%20shades%20of%20red"&gt;&lt;/figure&gt; &lt;p&gt;
If you have read my earlier articles about my search for the perfect keyboard, you may have got an idea of what I was looking for. Namely a mechanical keyboard with a decent keyboard layout, optimized for my use case. I mostly do my writing with &lt;a href="https://www.gnu.org/software/emacs/"&gt;Emacs&lt;/a&gt;, and a lot of it is german text and programm code. In the meantime I found my perfect solution, and realized I had no article of it in my blog. So this is it, maybe it is of use for some of you.
&lt;/p&gt;
&lt;!-- TEASER_END --&gt;
&lt;h2 class="collapsible" id="org3ba8714"&gt;The keyboard&lt;/h2&gt;
&lt;div id="outline-container-org3ba8714" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org3ba8714"&gt;
&lt;p&gt;
My decision finally zeroed in on buying a conventional keyboard with MX-Switches, as they have that exact tactile feeling that is deeply satisfying while I type. They are a bit loud for an office environment with colleagues around, but as I only use the keyboard at home it is ok. I ordered it with some touch of my personal coloring taste, and a special keyboard layout, that I gave some thought beforehand.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="org03a3630"&gt;The thoughts&lt;/h2&gt;
&lt;div id="outline-container-org03a3630" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org03a3630"&gt;
&lt;p&gt;
Some of the thoughts I had, before I ordered the keyboard, were going into the use cases I have, and in the constraints that a normal keyboard is delivering to this use cases. Namely:
&lt;/p&gt;

&lt;ul class="org-ul"&gt;
&lt;li&gt;&lt;p&gt;
I type a lot of programming code
&lt;/p&gt;

&lt;p&gt;
The optimal keyboard layout for that would be most probably an american, because most programming languages were developed with an american keyboard in mind. Characters like [, { or | are easily reachable on those keyboards. Sadly
&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;
I write a lot of german text
&lt;/p&gt;

&lt;p&gt;
and that means I absolutely want to have Umlauts in my layout. The german layout has those keys to the right of the keyboard, where they rule out some of that keys that are crucial for programming on an american board. As a consequence the german layout makes heavy use of the AltGR key to shift into a layer in which those keys are reachable. Unfortunatly this key is normally pressed with the least sensible finger, the pinky. Which leads me to the next issue,
&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;
I write in Emacs
&lt;/p&gt;

&lt;p&gt;
The Emacs community has a concept that is called "&lt;a href="https://www.emacswiki.org/emacs/RepeatedStrainInjury"&gt;Emacs pinky syndrome&lt;/a&gt;" and refers to he fact that Emacs makes heavy use of all your auxiliary keys like Shift, Ctrl or Alt. there is an often quoted saying, that Emacs is just an abbreviation for Escape-Meta-Alt-Ctrl-Shift. And for most of that keys you have to press some letters with your left pinky on one of that keys. Sometimes even more than one of it.
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="org45859ea"&gt;The layout&lt;/h2&gt;
&lt;div id="outline-container-org45859ea" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-org45859ea"&gt;
&lt;p&gt;
The gist of that matter was space. I needed the space for the german Umlauts, as well as those coding keys, that are to find in an american layout. Oh, and more Meta-keys would be of help for Emacs, to eliminate those long key combinations that are hard to memorize.
&lt;/p&gt;

&lt;p&gt;
The solution got in reach, when I realized that I nearly never use the numbers in the numbers row at the top of the keyboard. Instead of there, I type them on the number pad to the right. And there it was: SPACE, THE FINAL FRONTIER! Ah, and &lt;a href="https://uxmag.com/articles/the-trouble-with-caps-lock-wtfux"&gt;nobody needs CapsLock&lt;/a&gt; either.
&lt;/p&gt;

&lt;p&gt;
So I began to move all those keys that are only reachable via the AltGr key to the upper number row, leaving as much characters as possible in place that were already in the top row except numbers. All brackety chars ({[&amp;lt;&amp;gt;]}) are now on only 4 keys (7,8,9,0) which causes the only relocation that was needed. The = char had to move to the right to give way for the &amp;gt;, and so also the ? had to move and I chose to place it on the key where the 1 once was, so it is right below the !. 
&lt;/p&gt;

&lt;p&gt;
Following the same idea the ' was placed on the same key as the " so I have all quoting chars on one key, To use the normal chars used for quoting a string there is now no need for a Shift key anymore. That made place for the ~ which moved a key down, and can now be typed with just Shift instead of the pinky-heavy AltGr.
&lt;/p&gt;

&lt;p&gt;
The only two keys left where now the | which I moved to the same key as the &amp;amp; (both are used in many programming languages as logical AND and OR). The now empty key on the lower left became home to the backslash, together with the normal slash as the un-shifted key.
The @ sign found it's home at the place of the former 3 together with the Euro sign when shifted.
&lt;/p&gt;

&lt;p&gt;
You can see the result in the following image:
&lt;/p&gt;

&lt;p&gt;
&lt;img src="https://plaindrops.de/images/de-code.png" alt="nil"&gt;
&lt;/p&gt;

&lt;p&gt;
To make Emacs a little bit easier to use I also made CapsLock the Super-key and the now unneeded AltGr became the Hyper-key. The Alt-key was named Meta (that would have been the correct name for it's function anyways).
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 class="collapsible" id="orgeaeb7ee"&gt;Conclusion&lt;/h2&gt;
&lt;div id="outline-container-orgeaeb7ee" class="outline-2 collapsme"&gt;
&lt;div class="outline-text-2" id="text-orgeaeb7ee"&gt;
&lt;p&gt;
Within two weeks I had fully memorized the positions of the moved keys, and I don't mix them up with the traditional layout I use at the office computer. This risk was, what held me back from using the &lt;a href="https://www.neo-layout.org/"&gt;NEO Layout&lt;/a&gt;, which is also optimized for Germans and programming use.
&lt;/p&gt;

&lt;p&gt;
The &lt;a href="https://en.wikipedia.org/wiki/Symbolics#/media/File:Symbolics-keyboard.jpg"&gt;Super and Hyper keys&lt;/a&gt; are great when using Emacs. I made me a still growing set of &lt;a href="https://github.com/abo-abo/hydra"&gt;Hydras&lt;/a&gt; and mapped it to the Hyper key (Hyper/Hydra made it very easy to memorize). The Super key becomes more useful to call whole Emacs modes like &lt;a href="https://www.emacswiki.org/emacs/mu4e"&gt;mu4e&lt;/a&gt;, &lt;a href="https://magit.vc/"&gt;magit&lt;/a&gt; or calendar modes.
&lt;/p&gt;

&lt;p&gt;
As a side effect I never get stuck in CapsLock anymore, so no more badly typed password three times in a row.
&lt;/p&gt;

&lt;p&gt;
The feeling that "something is wrong" while I type had completely gone, and now it feels so naturally, that i'm far less distracted, and could finally better concentrate on the content.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description><category>coding</category><category>de-code</category><category>emacs</category><category>keyboard</category><guid>https://plaindrops.de/blog/2018/de-code/</guid><pubDate>Mon, 22 Oct 2018 22:00:00 GMT</pubDate></item></channel></rss>