<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>cottontailia.io</title>
    <subtitle>A log of building, breaking, and fixing things in the Emacs ecosystem.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://cottontailia.github.io/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://cottontailia.github.io/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-02-19T00:00:00+00:00</updated>
    <id>https://cottontailia.github.io/atom.xml</id>
    <entry xml:lang="en">
        <title>The Day Tree-sitter Killed Portability</title>
        <published>2026-02-19T00:00:00+00:00</published>
        <updated>2026-02-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://cottontailia.github.io/the-day-tree-sitter-killed-portability/"/>
        <id>https://cottontailia.github.io/the-day-tree-sitter-killed-portability/</id>
        
        <content type="html" xml:base="https://cottontailia.github.io/the-day-tree-sitter-killed-portability/">&lt;p&gt;Same Emacs 29.2. Same config file.&lt;br &#x2F;&gt;
It worked perfectly on macOS.&lt;br &#x2F;&gt;
I copied it to Windows. Tree-sitter died.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;treesit-load-language-error: Cannot load language rust&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ABI version mismatch (library: 15, runtime: 14)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I checked.&lt;br &#x2F;&gt;
macOS build: &lt;code&gt;(treesit-library-abi-version)&lt;&#x2F;code&gt; → &lt;strong&gt;15&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
Windows build: &lt;code&gt;(treesit-library-abi-version)&lt;&#x2F;code&gt; → &lt;strong&gt;14&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s when I realized.&lt;br &#x2F;&gt;
The 10-year assumption of &quot;portable init.el&quot; had just collapsed.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;act-1-the-migration-nightmare&quot;&gt;Act 1: The Migration Nightmare&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;the-first-wall-grammar-not-found&quot;&gt;The First Wall: &quot;Grammar not found&quot;&lt;&#x2F;h3&gt;
&lt;p&gt;I had spent weeks perfecting my Emacs setup on macOS. Same version. Same packages. Same config file. I copied it to my Windows machine.&lt;&#x2F;p&gt;
&lt;p&gt;I opened a Rust file.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Cannot find tree-sitter grammar for rust&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&quot;Just not installed yet.&quot;&lt;br &#x2F;&gt;
I ran &lt;code&gt;M-x treesit-install-language-grammar&lt;&#x2F;code&gt;.&lt;br &#x2F;&gt;
Entered the repository URL.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;treesit-install-language-grammar: Cannot find a C compiler&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;the-msys2-swamp&quot;&gt;The MSYS2 Swamp&lt;&#x2F;h3&gt;
&lt;p&gt;I Googled. Every article gave the same answer.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&quot;Install MSYS2&quot;&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Download: &lt;strong&gt;3.5GB&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Install time: 30 minutes&lt;&#x2F;li&gt;
&lt;li&gt;PATH configuration&lt;&#x2F;li&gt;
&lt;li&gt;Restart Emacs&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I tried again.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Error: cc1.exe not found&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Another search.&lt;&#x2F;p&gt;
&lt;p&gt;&quot;You need &lt;code&gt;mingw-w64-x86_64-gcc&lt;&#x2F;code&gt;&quot;&lt;&#x2F;p&gt;
&lt;p&gt;Installed via pacman.&lt;br &#x2F;&gt;
Another restart.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, compilation succeeded.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-gateway-to-abi-hell&quot;&gt;The Gateway to ABI Hell&lt;&#x2F;h3&gt;
&lt;p&gt;I opened a Rust file.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;treesit-load-language-error: Cannot load language rust&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ABI version mismatch (library: 15, runtime: 14)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&quot;What is this?&quot;&lt;&#x2F;p&gt;
&lt;p&gt;I checked.&lt;br &#x2F;&gt;
Windows build of Emacs 29.2 supports &lt;strong&gt;ABI 14&lt;&#x2F;strong&gt; at most.&lt;br &#x2F;&gt;
macOS build of the same Emacs 29.2 supports &lt;strong&gt;ABI 15&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Same version number. Different capabilities.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In that moment, I realized the &quot;portable config file&quot; had been a lie.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;act-2-four-circles-of-hell&quot;&gt;Act 2: Four Circles of Hell&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;hell-1-platform-dependent-abi-fragmentation&quot;&gt;Hell 1: Platform-Dependent ABI Fragmentation&lt;&#x2F;h3&gt;
&lt;p&gt;Same Emacs 29.2, but:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;macOS: ABI 15 supported&lt;&#x2F;li&gt;
&lt;li&gt;Windows: ABI 14 only&lt;&#x2F;li&gt;
&lt;li&gt;Linux (distribution-dependent): 13, 14, 15 mixed&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Grammar settings in init.el won&#x27;t work on another machine.&lt;br &#x2F;&gt;
Because &lt;strong&gt;Emacs capabilities vary by build conditions&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hell-2-crashes-even-when-abi-matches&quot;&gt;Hell 2: Crashes Even When ABI Matches&lt;&#x2F;h3&gt;
&lt;p&gt;&quot;Fine, I&#x27;ll just use ABI 14 grammars.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;I installed the latest rust grammar on macOS.&lt;br &#x2F;&gt;
ABI check: &lt;strong&gt;14&lt;&#x2F;strong&gt;&lt;br &#x2F;&gt;
Emacs support: &lt;strong&gt;15&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&quot;Perfect.&quot;&lt;&#x2F;p&gt;
&lt;p&gt;I opened a file.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Emacs crashed. Segfault. No error message.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I searched.&lt;br &#x2F;&gt;
Buried in a GitHub issue:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;ABI 14 has internal breaking changes between tree-sitter 0.20.x and 0.21.x&quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Same version number. Different internals.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Which commit actually works with my Emacs?&lt;br &#x2F;&gt;
Trial and error is the only way.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hell-3-the-windows-3-5gb-tax&quot;&gt;Hell 3: The Windows &quot;3.5GB Tax&quot;&lt;&#x2F;h3&gt;
&lt;p&gt;To get a few kilobytes of syntax highlighting:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;MSYS2: 3.5GB&lt;&#x2F;li&gt;
&lt;li&gt;mingw-w64-toolchain: hundreds of MB&lt;&#x2F;li&gt;
&lt;li&gt;PATH conflicts&lt;&#x2F;li&gt;
&lt;li&gt;Build error debugging&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Polluting the OS just to get a .so file.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;hell-4-configuration-fragmentation&quot;&gt;Hell 4: Configuration Fragmentation&lt;&#x2F;h3&gt;
&lt;p&gt;I want to add Rust.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;;; 1. Define repository&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;add-to-list&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;treesit-language-source-alist&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;             &amp;#39;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;rust &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;https:&#x2F;&#x2F;github.com&#x2F;tree-sitter&#x2F;tree-sitter-rust&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;;; 2. Install (manual execution)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;;; M-x treesit-install-language-grammar&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;;; 3. Bind major mode&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;add-to-list&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;major-mode-remap-alist&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;#39;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;rust-mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; .&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; rust-ts-mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;;; 4. Bind file extension&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;add-to-list&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;auto-mode-alist&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;#39;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;\\.rs\\&amp;#39;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; .&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; rust-ts-mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I want to add TypeScript.&lt;br &#x2F;&gt;
Repeat the same process.&lt;&#x2F;p&gt;
&lt;p&gt;Python, YAML, Markdown...&lt;&#x2F;p&gt;
&lt;p&gt;Settings are now scattered across 4 places in init.el.&lt;br &#x2F;&gt;
When I want to remove a language, I don&#x27;t know where to delete.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;This is maintenance hell.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;act-3-the-obsession-begins&quot;&gt;Act 3: The Obsession Begins&lt;&#x2F;h2&gt;
&lt;p&gt;I spent 6 hours fighting MSYS2.&lt;br &#x2F;&gt;
I manually traversed Git history to find compatible commits.&lt;br &#x2F;&gt;
On the third night, I decided.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&quot;Never again.&quot;&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll hijack Emacs&#x27;s internal functions if I have to.&lt;br &#x2F;&gt;
I&#x27;ll brute-force scan Git repositories if I have to.&lt;&#x2F;p&gt;
&lt;p&gt;This isn&#x27;t a &quot;convenient tool.&quot;&lt;br &#x2F;&gt;
&lt;strong&gt;This is infrastructure born from obsession.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;the-solution-treesit-env-el&quot;&gt;The Solution: treesit-env.el&lt;&#x2F;h2&gt;
&lt;p&gt;I built four weapons.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;weapon-1-brute-force-git-history-search&quot;&gt;Weapon 1: Brute-Force Git History Search&lt;&#x2F;h3&gt;
&lt;p&gt;&quot;I don&#x27;t know which commit works.&quot;&lt;br &#x2F;&gt;
&lt;strong&gt;Then try them all.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;while&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;and&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; current-abi abi-max&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;) (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; attempt limit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;  ;; Deepen history by 10 commits at a time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;call-process&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;git&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil nil nil&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;fetch&amp;quot; &amp;quot;--deepen&amp;quot; &amp;quot;10&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;dolist&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;commit new-commits&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;with-temp-buffer&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;      ;; Read file without checkout&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;      (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;call-process&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;git&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;show&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;format&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;%s:src&#x2F;parser.c&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; commit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;      &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;      ;; Parse LANGUAGE_VERSION with regex&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;      (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;goto-char&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;point-min&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;      (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;when&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;re-search-forward&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;LANGUAGE_VERSION[ &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;\&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-punctuation z-definition z-string&quot;&gt;t]+\\([0-9]+\\)&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;setq current-abi &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;string-to-number&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;match-string&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;      &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;      ;; Checkout immediately when compatible&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;      (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;when&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt;&amp;lt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; current-abi abi-max&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;call-process&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;git&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil nil nil&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;checkout&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; commit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;throw&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;found commit&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;How it works:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Dig into history with &lt;code&gt;git fetch --deepen&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Read files directly with &lt;code&gt;git show COMMIT:src&#x2F;parser.c&lt;&#x2F;code&gt; (no checkout needed)&lt;&#x2F;li&gt;
&lt;li&gt;Extract &lt;code&gt;LANGUAGE_VERSION&lt;&#x2F;code&gt; via regex&lt;&#x2F;li&gt;
&lt;li&gt;Stop the moment ABI is within limits&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;It&#x27;s slow. Network-heavy.&lt;br &#x2F;&gt;
&lt;strong&gt;But it never fails.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;weapon-2-compiler-hijacking&quot;&gt;Weapon 2: Compiler Hijacking&lt;&#x2F;h3&gt;
&lt;p&gt;&quot;MSYS2 is too heavy.&quot;&lt;br &#x2F;&gt;
&lt;strong&gt;Use Zig. A single 200MB binary.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&quot;But Emacs expects gcc.&quot;&lt;br &#x2F;&gt;
&lt;strong&gt;Then lie to it.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;cl-letf*&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (((&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;symbol-function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;executable-find&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;lambda&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;command&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;              ;; Looking for &amp;quot;gcc&amp;quot;? → Return Zig instead&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;              (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;let&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;base &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;file-name-sans-extension&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                          (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;file-name-nondirectory&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; command&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;cond&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;member&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; base &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;cc&amp;quot; &amp;quot;gcc&amp;quot; &amp;quot;clang&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                       (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;car&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; treesit-env-compiler-cc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                      ((&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;member&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; base &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;c++&amp;quot; &amp;quot;g++&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                       (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;car&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; treesit-env-compiler-c++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                      (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;t&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;funcall&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; old-exec-find command&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;           &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;           ((&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;symbol-function&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;call-process&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;            (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;lambda&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;program&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; &amp;amp;rest&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt; args&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;              ;; Missing .o files during linking? → Auto-inject them&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;              (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;when&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;and&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;member&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;-shared&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; args&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                         (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;not&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;cl-some&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;lambda&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                                        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;string-match-p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;\\.o$&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; a&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;                                      args&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;setq args &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;append&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; args &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;                                  (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;directory-files&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;.&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;\\.o$&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;              (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;apply&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; old-call-process program args&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;What&#x27;s happening:&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Emacs believes &quot;gcc exists.&quot;&lt;br &#x2F;&gt;
I decided to return Zig.&lt;&#x2F;p&gt;
&lt;p&gt;Emacs expects &quot;.o files as arguments.&quot;&lt;br &#x2F;&gt;
I decided to scan the directory and inject them.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;This isn&#x27;t a &quot;hack.&quot; It&#x27;s obsession.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;weapon-3-declarative-configuration&quot;&gt;Weapon 3: Declarative Configuration&lt;&#x2F;h3&gt;
&lt;p&gt;&quot;Settings are scattered.&quot;&lt;br &#x2F;&gt;
&lt;strong&gt;Centralize them.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;treesit-env rust&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;vc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;tree-sitter&#x2F;tree-sitter-rust&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;\\.rs\\&amp;#39;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;revision auto&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;  ;; Auto-search Git history&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s it.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Repository definition&lt;&#x2F;li&gt;
&lt;li&gt;Installation&lt;&#x2F;li&gt;
&lt;li&gt;Mode binding&lt;&#x2F;li&gt;
&lt;li&gt;ABI compatibility search&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;Everything is automatic.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;weapon-4-recipe-dump&quot;&gt;Weapon 4: Recipe Dump&lt;&#x2F;h3&gt;
&lt;p&gt;&quot;Someone should maintain the canonical recipes.&quot;&lt;br &#x2F;&gt;
&lt;strong&gt;No. Let the community share them.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;M-x treesit-env-dump-recipes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This outputs your working configuration in recipe format.&lt;br &#x2F;&gt;
Paste it in a Gist. Post it in a forum.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;No centralized maintainer needed.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;basic-setup&quot;&gt;Basic Setup&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;use-package&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; treesit-env&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;vc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;url&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;https:&#x2F;&#x2F;github.com&#x2F;cottontailia&#x2F;treesit-env&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;custom&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;treesit-env-default-revision-auto t&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;  ;; Auto ABI search&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;treesit-env-abi-max &lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;14&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;               ;; Force ABI 14 or lower&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;config&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;  ;; Use Zig on Windows&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;when&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;eq&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; system-type &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;windows-nt&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;setq treesit-env-compiler-cc &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;zig&amp;quot; &amp;quot;cc&amp;quot; &amp;quot;-O3&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;setq treesit-env-compiler-c++ &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;&amp;#39;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot;zig&amp;quot; &amp;quot;c++&amp;quot; &amp;quot;-O3&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;  ;; Activate languages&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;treesit-env rust python typescript&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;pattern-collection&quot;&gt;Pattern Collection&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;;; Pattern 1: Official repository (short form)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;treesit-env rust&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;  ;; → tree-sitter&#x2F;tree-sitter-rust&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;;; Pattern 2: tree-sitter-grammars org&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;treesit-env markdown &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;vc grammars&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;;; Pattern 3: Custom repository&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;treesit-env python &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;vc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;user&#x2F;custom-python-grammar&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;;; Pattern 4: Auto ABI search&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;treesit-env go &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;revision auto&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;;; Pattern 5: Fixed revision (fastest)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;treesit-env rust &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;revision&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;v0.20.4&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;;; Pattern 6: Auto dependency resolution&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;treesit-env tsx &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;deps typescript&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;;; Pattern 7: Monorepo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;treesit-env typescript &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;vc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;tree-sitter&#x2F;tree-sitter-typescript&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;src-path&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;typescript&#x2F;src&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;;; Pattern 8: Multiple extensions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;treesit-env javascript &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;  :&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;\\.js\\&amp;#39;&amp;quot; &amp;quot;\\.mjs\\&amp;#39;&amp;quot; &amp;quot;\\.cjs\\&amp;#39;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;hr &#x2F;&gt;
&lt;h3 id=&quot;recipe-definition-and-sharing&quot;&gt;Recipe Definition and Sharing&lt;&#x2F;h3&gt;
&lt;p&gt;Complete examples: see &lt;code&gt;treesit-env-recipe-placeholder.el&lt;&#x2F;code&gt; in the repository.&lt;br &#x2F;&gt;
&lt;strong&gt;Warning&lt;&#x2F;strong&gt;: It&#x27;s a &quot;placeholder&quot;—minimal recipes, no maintenance promise.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;;; Define recipes with treesit-env-recipes macro&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;defconst&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; my-recipes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;treesit-env-recipes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;   (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;rust &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;vc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;tree-sitter&#x2F;tree-sitter-rust&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt; :&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;revision&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;v0.20.4&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;   (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;python &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;vc grammars &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;mode&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;\\.py\\&amp;#39;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;   (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;typescript &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;deps tsx &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;src-path&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;typescript&#x2F;src&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;;; Import with treesit-env-source&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;treesit-env-source my-recipes&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;;; M-x treesit-env-dump-recipes outputs in this format too&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Copy someone&#x27;s success. Share yours.&lt;br &#x2F;&gt;
&lt;strong&gt;Decentralized ecosystem.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;under-the-hood-technical-deep-dive&quot;&gt;Under the Hood: Technical Deep Dive&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;why-read-parser-c-directly&quot;&gt;Why Read parser.c Directly?&lt;&#x2F;h3&gt;
&lt;p&gt;Tree-sitter maintainers don&#x27;t care about Emacs.&lt;br &#x2F;&gt;
They race forward toward the latest library (ABI 15).&lt;&#x2F;p&gt;
&lt;p&gt;Version info in GitHub READMEs is unreliable.&lt;br &#x2F;&gt;
Tags can&#x27;t be trusted.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The only truth is the source code.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;At the top of &lt;code&gt;src&#x2F;parser.c&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-directive z-keyword z-control z-directive&quot;&gt;#define&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function&quot;&gt; LANGUAGE_VERSION&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 14&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Read this.&lt;br &#x2F;&gt;
Only this tells you &quot;Is this commit really ABI 14?&quot;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-madness-of-zig-hijacking&quot;&gt;The Madness of Zig Hijacking&lt;&#x2F;h3&gt;
&lt;p&gt;Emacs&#x27;s build system is stubborn.&lt;&#x2F;p&gt;
&lt;p&gt;It expects specific compiler names (&lt;code&gt;gcc&lt;&#x2F;code&gt;, &lt;code&gt;g++&lt;&#x2F;code&gt;).&lt;br &#x2F;&gt;
It expects specific argument orders.&lt;br &#x2F;&gt;
It expects specific file naming conventions.&lt;&#x2F;p&gt;
&lt;p&gt;Zig doesn&#x27;t satisfy these.&lt;&#x2F;p&gt;
&lt;p&gt;So when Emacs &quot;calls gcc,&quot; I &lt;strong&gt;run Zig instead&lt;&#x2F;strong&gt; behind the scenes.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;;; Emacs&amp;#39;s perspective&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;call-process&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;gcc&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;-shared&amp;quot; &amp;quot;-o&amp;quot; &amp;quot;rust.so&amp;quot; &amp;quot;parser.c&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;;; Actual execution&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;call-process&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;zig&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; t&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;cc&amp;quot; &amp;quot;-O3&amp;quot; &amp;quot;-shared&amp;quot; &amp;quot;-o&amp;quot; &amp;quot;rust.so&amp;quot; &amp;quot;parser.c&amp;quot; &amp;quot;parser.o&amp;quot; &amp;quot;scanner.o&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Those &lt;code&gt;.o&lt;&#x2F;code&gt; files at the end? I injected them.&lt;br &#x2F;&gt;
Because Zig&#x27;s linker requires explicit file lists.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Emacs knows nothing. It just sees &quot;build succeeded.&quot;&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;recursive-dependency-resolution&quot;&gt;Recursive Dependency Resolution&lt;&#x2F;h3&gt;
&lt;p&gt;tsx depends on typescript.&lt;br &#x2F;&gt;
C depends on cpp (sometimes).&lt;&#x2F;p&gt;
&lt;p&gt;Users don&#x27;t know this. They don&#x27;t need to.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;emacs-lisp&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;defvar&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; treesit-env--installing-stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language&quot;&gt; nil&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type&quot;&gt;defun&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; treesit-env--execute-install&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter&quot;&gt;recipe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;  (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;let&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; ((&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;lang &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;plist-get&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; recipe &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;lang&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;deps &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;plist-get&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; recipe &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword&quot;&gt;:&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;deps&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    ;; Detect circular dependencies&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;when&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;memq&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; lang treesit-env--installing-stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;      (&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function&quot;&gt;error&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;Circular dependency detected: %s&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; lang&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    ;; Install dependencies first&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;push&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; lang treesit-env--installing-stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;dolist&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;dep deps&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;      (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;unless&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt; (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;treesit-language-available-p dep&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;        (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;treesit-env--execute-install &lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;get-recipe dep&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;))))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt;pop&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; treesit-env--installing-stack&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;    ;; Install the language itself&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;    (&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;treesit-env--compile recipe&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Simple. Reliable.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Users never think about dependencies.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;philosophy-why-cc0&quot;&gt;Philosophy: Why CC0?&lt;&#x2F;h2&gt;
&lt;p&gt;This tool was born from personal rage.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;6 hours fighting MSYS2&lt;&#x2F;li&gt;
&lt;li&gt;Manual Git history traversal&lt;&#x2F;li&gt;
&lt;li&gt;Config files that won&#x27;t work across 3 machines&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This isn&#x27;t &quot;innovative algorithm.&quot;&lt;br &#x2F;&gt;
It&#x27;s &lt;strong&gt;plumbing work&lt;&#x2F;strong&gt; to make unstable Tree-sitter infrastructure usable.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s why I chose CC0 (Public Domain).&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t seek stars or contributors.&lt;br &#x2F;&gt;
I just wanted an environment that works &lt;strong&gt;the same way on any machine&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;why-i-won-t-maintain-recipes&quot;&gt;Why I Won&#x27;t Maintain Recipes&lt;&#x2F;h3&gt;
&lt;p&gt;I don&#x27;t want to be a &quot;URL maintainer.&quot;&lt;br &#x2F;&gt;
I want to write code.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s why I created &lt;code&gt;treesit-env-dump-recipes&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;You can export your working config.&lt;br &#x2F;&gt;
Paste it in a Gist. Post it on Reddit. Copy it to someone&#x27;s blog.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Let the community self-organize.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Centralized databases are fragile.&lt;br &#x2F;&gt;
Distributed knowledge is resilient.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;If you&#x27;ve ever:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Been lost after seeing &quot;ABI mismatch&quot;&lt;&#x2F;li&gt;
&lt;li&gt;Regretted installing MSYS2&lt;&#x2F;li&gt;
&lt;li&gt;Despaired when your config broke on another machine&lt;&#x2F;li&gt;
&lt;li&gt;Manually traversed Git history to find working commits&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;&lt;strong&gt;This tool is for you.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This isn&#x27;t a perfect solution.&lt;br &#x2F;&gt;
Someday, when Emacs and Tree-sitter mature, tools like this won&#x27;t be needed.&lt;&#x2F;p&gt;
&lt;p&gt;But today, you&#x27;re suffering.&lt;&#x2F;p&gt;
&lt;p&gt;So I&#x27;m releasing this infrastructure born from obsession.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;strong&gt;GitHub&lt;&#x2F;strong&gt;: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cottontailia&#x2F;treesit-env&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;cottontailia&#x2F;treesit-env&lt;&#x2F;a&gt;&lt;br &#x2F;&gt;
&lt;strong&gt;License&lt;&#x2F;strong&gt;: CC0 (Public Domain)&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
