{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreicivtkwhf4x7dwcygbly2hzmwjkcxgulu3rcdxrpjurxj7ygejpgm",
"commit": {
"cid": "bafyreifz6dzizf7b4jofhwmtb3iztufneiglh4lcalguhvcn6ysdcufl6m",
"rev": "3mpq7n7vacr2t"
},
"uri": "at://did:plc:c2donbgbos6qiylm4evc6wsi/app.bsky.feed.post/3mpq7n7snwk26",
"validationStatus": "valid"
},
"content": {
"$type": "pub.leaflet.content",
"pages": [
{
"$type": "pub.leaflet.pages.linearDocument",
"blocks": [
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"plaintext": "In my head, code editors fall on a spectrum of intuition on one side or flexibility on the other. Easy versus malleable. I know this is an oversimplification, but bear with me for a bit."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"features": [
{
"$type": "pub.leaflet.richtext.facet#link",
"uri": "https://xkcd.com/1343/"
}
],
"index": {
"byteEnd": 128,
"byteStart": 109
}
}
],
"plaintext": "On one hand, we have VS Code, Sublime Text and similar editors, which are pretty intuitive for newcomers and don't need a manual. They can be extended with plugins, but the inner workings of the editor are only used by plugin developers. The common way to use these editors is to understand the default, prescribed workflow, maybe change a few surface-level things, install some plugins and get going."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"plaintext": "On the other end of the spectrum are hyper-flexible editors like Emacs and Neovim. These are not for beginners, but the steep learning curve also exposes you to the internal mechanisms of the editor, giving you a mental model of how the editor works as a system rather than as an interface. And once you understand a system, you understand how to change it, extend it, repurpose it or even limit it."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"plaintext": "A characteristic feature of these editors is that there is no single prescribed workflow. You are encouraged to evolve one based on your usage and preferences. The editor gives you the tools; you build the house. Your house looks nothing like mine."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"plaintext": "Two arbitrary people using VS Code are likely to have mostly similar workflows. Two arbitrary people using Neovim might do it so differently they'd find it difficult to use each other's setup. Because VS Code optimizes for intuition by prescribing a workflow, while Neovim optimizes for flexibility by giving you the means to build your workflow."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"plaintext": "Now that we have established a simplistic mental model, it's time to break it. There are two categories of editors that are hard to place on this spectrum:"
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.unorderedList",
"children": [
{
"$type": "pub.leaflet.blocks.unorderedList#listItem",
"content": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"features": [
{
"$type": "pub.leaflet.richtext.facet#link",
"uri": "https://www.spacemacs.org/"
}
],
"index": {
"byteEnd": 36,
"byteStart": 27
}
},
{
"features": [
{
"$type": "pub.leaflet.richtext.facet#link",
"uri": "https://doomemacs.org/"
}
],
"index": {
"byteEnd": 48,
"byteStart": 38
}
},
{
"features": [
{
"$type": "pub.leaflet.richtext.facet#footnote",
"contentPlaintext": "Emacs and Vim are complex systems (in a positive way) and understanding this complexity is how you craft your workflow. My main problem with preconfigured distributions is that they try to cover up the good complexity under a simple-looking veneer. The true beauty of Emacs and Vim is in the complexity.",
"footnoteId": "019f273a-730b-7ddd-99c9-ddb437fd9f04"
}
],
"index": {
"byteEnd": 447,
"byteStart": 446
}
}
],
"plaintext": "Distributions. Things like Spacemacs, Doom Emacs or the various Neovim distros are trying to bring the intuition of modern editors to the flexible ones, but in my experience, they achieve neither. Their setup does little to educate you about the underlying flexibility, but they are also not a breeze to use for newcomers. Every time I have tried to use one of these, I have given up in a few weeks. The defaults take you far, but not far enough.* When you have to get your hands dirty to change that one obscure thing, you are left clueless. Perhaps the problem lies with my expectations and not with the distros, but they're not for me."
}
},
{
"$type": "pub.leaflet.blocks.unorderedList#listItem",
"content": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"features": [
{
"$type": "pub.leaflet.richtext.facet#link",
"uri": "https://helix-editor.com/"
}
],
"index": {
"byteEnd": 5,
"byteStart": 0
}
}
],
"plaintext": "Helix, the underdog that flies in the face of convention. It's nowhere near as malleable as Vim or Emacs, and its learning curve is decidedly steeper than that of Sublime Text. And yet, learning Helix pays off, because it has made excellent design decisions. There are no plugins, but most of the time, you don't need any. Its selection-first editing approach makes so much more sense than Vim's action-first model. For me, it consumes far fewer mental cycles thinking what a given action will do in Helix compared to the guesswork involved in Vim."
}
}
]
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"plaintext": "A couple years ago, I started using Helix. And to learn it, I applied the same strategy that I did while learning to touch-type: force myself to slowly and painstakingly use the correct idioms until they become muscle memory. And they did. The effort to learn Helix paid off really well without the maintenance burden of a hand-crafted configuration. For my day-to-day JS and Python needs, Helix was more than enough."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"features": [
{
"$type": "pub.leaflet.richtext.facet#link",
"uri": "https://www.scheme.org/"
}
],
"index": {
"byteEnd": 38,
"byteStart": 32
}
},
{
"features": [
{
"$type": "pub.leaflet.richtext.facet#link",
"uri": "https://fennel-lang.org/"
}
],
"index": {
"byteEnd": 49,
"byteStart": 43
}
}
],
"plaintext": "Only when I took an interest in Scheme and Fennel (both Lisp dialects) did I feel the need to try something new: for programming in Lisp dialects, Emacs remains the unbeaten king. So I found myself at a crossroads: stick with Helix's comfort and live with limited integration with Lisps, or move to Emacs and rewire my muscle memory in favour of a better Lisp editing environment."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"plaintext": "I bet on the latter, and it worked."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"plaintext": "My first attempt was to try Doom Emacs + Evil mode and retrofit Helix-like keybindings into Evil mode. It worked to an extent, but for the aforementioned reasons, I found myself spending more time in the config file than doing any actual programming. It was fun, mind you, but I was learning more about configuring individual packages than about Emacs itself."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"features": [
{
"$type": "pub.leaflet.richtext.facet#link",
"uri": "https://github.com/SystemCrafters/crafted-emacs"
}
],
"index": {
"byteEnd": 225,
"byteStart": 212
}
}
],
"plaintext": "So my second pass was to roll up my sleeves and craft my system from the ground up. Instead of going for a full-blown distribution, I started with vanilla GNU Emacs. Then I pulled the bread-and-butter stuff from Crafted Emacs, a highly modular system that takes care of the inconvenient defaults but gives you far more control over what new packages you add. It prefers building upon what is included with Emacs instead of reinventing the wheel. But most importantly, it educates you and encourages you to actually write some Emacs Lisp instead of treating it like glorified settings dialog."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"features": [
{
"$type": "pub.leaflet.richtext.facet#link",
"uri": "https://git.sr.ht/~dar5hak/dotfiles/tree/main/item/emacs/init.el"
}
],
"index": {
"byteEnd": 172,
"byteStart": 166
}
}
],
"plaintext": "Using this knowledge, I was able to replicate ~90% of my previous Doom setup with about 1/3rd as many packages, and what's more, I understand every single line of my config."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"plaintext": "When it comes to replicating Helix's selection-first editing model, Crafted Emacs doesn't offer any pre-built configuration. But it does offer a philosophy: pick something that relies on the Emacs built-ins rather than something that deviates from the platform."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"features": [
{
"$type": "pub.leaflet.richtext.facet#link",
"uri": "https://github.com/meow-edit/meow"
}
],
"index": {
"byteEnd": 46,
"byteStart": 37
}
}
],
"plaintext": "Going by that, the answer was clear: Meow mode."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"plaintext": "From its introduction:"
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.blockquote",
"plaintext": "Meow aims to blend modal editing into Emacs with minimal interference with its original key-bindings, avoiding most of the hassle introduced by key-binding conflicts. This leads to lower necessary configuration and better integration. More is achieved with fewer commands to remember."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"plaintext": "Meow's ergonomics are so similar to Helix that you can do some basic editing and navigation right away without even going through the tutorial."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"plaintext": "The only differences that stood out to me are:"
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.unorderedList",
"children": [
{
"$type": "pub.leaflet.blocks.unorderedList#listItem",
"content": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"features": [
{
"$type": "pub.leaflet.richtext.facet#code"
}
],
"index": {
"byteEnd": 68,
"byteStart": 67
}
},
{
"features": [
{
"$type": "pub.leaflet.richtext.facet#code"
}
],
"index": {
"byteEnd": 84,
"byteStart": 83
}
},
{
"features": [
{
"$type": "pub.leaflet.richtext.facet#code"
}
],
"index": {
"byteEnd": 116,
"byteStart": 115
}
},
{
"features": [
{
"$type": "pub.leaflet.richtext.facet#code"
}
],
"index": {
"byteEnd": 150,
"byteStart": 149
}
},
{
"features": [
{
"$type": "pub.leaflet.richtext.facet#code"
}
],
"index": {
"byteEnd": 162,
"byteStart": 161
}
},
{
"features": [
{
"$type": "pub.leaflet.richtext.facet#code"
}
],
"index": {
"byteEnd": 227,
"byteStart": 226
}
}
],
"plaintext": "Reverse operations work differently. In Helix, you would undo with u and redo with U. In Meow, you would undo with u but then change directions with ; and reuse u to redo. Likewise for finding the next match of a pattern with n. I don't prefer one approach over the other, so this was just a matter or adjusting my muscle memory."
}
},
{
"$type": "pub.leaflet.blocks.unorderedList#listItem",
"content": {
"$type": "pub.leaflet.blocks.text",
"plaintext": "Multiple cursor editing works differently. I won't explain it in detail, but this is one area where I find Helix's approach more intuitive. For any serious multi-cursor workload, I fire up VSCodium and get on with my day."
}
}
]
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"plaintext": "Lastly, two more packages gave me a complete, productive Lisp experience:"
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.unorderedList",
"children": [
{
"$type": "pub.leaflet.blocks.unorderedList#listItem",
"content": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"features": [
{
"$type": "pub.leaflet.richtext.facet#link",
"uri": "https://github.com/abo-abo/avy"
}
],
"index": {
"byteEnd": 3,
"byteStart": 0
}
}
],
"plaintext": "Avy lets you jump anywhere in a few keystrokes, effectively eliminating the need for a mouse."
}
},
{
"$type": "pub.leaflet.blocks.unorderedList#listItem",
"content": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"features": [
{
"$type": "pub.leaflet.richtext.facet#link",
"uri": "https://paredit.org/"
}
],
"index": {
"byteEnd": 7,
"byteStart": 0
}
}
],
"plaintext": "Paredit lets you handle Lisp code in a more structural manner. Instead of treating it as a collection of words and symbols, you treat it as a tree of expressions. It's as if you're directly editing the AST, because with Lisps, you pretty much are."
}
}
]
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"features": [
{
"$type": "pub.leaflet.richtext.facet#link",
"uri": "https://orgmode.org/"
}
],
"index": {
"byteEnd": 146,
"byteStart": 138
}
}
],
"plaintext": "After spending a few months with this setup, I feel right at home, not just with Lisp programming, but with any language. I even took the Org Mode pill and started maintaining a part of my to-dos in Emacs itself."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"plaintext": "I'm still exploring ways to personalize this new environment and am open to suggestions, but the rhythm is in place."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"features": [
{
"$type": "pub.leaflet.richtext.facet#link",
"uri": "https://git.sr.ht/~dar5hak/dotfiles"
}
],
"index": {
"byteEnd": 54,
"byteStart": 41
}
}
],
"plaintext": "If you want to see my config, head to my dotfiles repo. If you found this post useful, feel free to reach out and share your thoughts."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"plaintext": "Happy hacking."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"plaintext": ""
}
}
],
"id": "019f1bec-1612-7ff3-ac71-6455c386d0e6"
}
]
},
"description": "",
"path": "/3mpq7myieuc26",
"publishedAt": "2026-07-03T09:17:45.477Z",
"site": "at://did:plc:c2donbgbos6qiylm4evc6wsi/site.standard.publication/3mortnrktis2l",
"tags": [
"emacs",
"vim",
"neovim",
"lisp",
"helix",
"meow",
"modal editing",
"programming",
"text editors"
],
"title": "Emacs + Meow is an underrated combo"
}