惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

MyScale Blog
MyScale Blog
A
About on SuperTechFans
G
Google Developers Blog
B
Blog RSS Feed
F
Fortinet All Blogs
WordPress大学
WordPress大学
Recent Announcements
Recent Announcements
Hugging Face - Blog
Hugging Face - Blog
Y
Y Combinator Blog
MongoDB | Blog
MongoDB | Blog
小众软件
小众软件
人人都是产品经理
人人都是产品经理
博客园 - 叶小钗
T
The Blog of Author Tim Ferriss
Jina AI
Jina AI
IT之家
IT之家
P
Proofpoint News Feed
美团技术团队
量子位
Microsoft Azure Blog
Microsoft Azure Blog
Engineering at Meta
Engineering at Meta
B
Blog
有赞技术团队
有赞技术团队
U
Unit 42

Computer Things

The LLMs yearn for the spines New Post: A Crash Course in Predicate Logic Logic for Programmers is Done I'm still alive Logic for Programmers v0.15, Livecoding Nontrailing separators do not spark joy Logic for Programmers extra credits Knowing about things is cheaper than knowing things Assumptions weaken properties Points are a weird and inconsistent unit of measure New Logic for Programmers (and the future of this newsletter) Illegal vs Unwanted States People get confused when language implementations break language guarantees A sufficiently comprehensive spec is not (necessarily) code April Cools Post: New York vs Chicago Pizza Choose Boring Technology and Innovative Practices LLMs are bad at vibing specifications Free Books New Blog Post: Some Silly Z3 Scripts I Wrote Stream of Consciousness Driven Development Proving What's Possible Logic for Programmers New Release and Next Steps Refinement without Specification My Gripes with Prolog The Liskov Substitution Principle does more than you think Some Fun Software Facts One more week to the Logic for Programmers Food Drive Get Logic for Programmers 50% off & Support Chicago Foodbanks I'm taking a break Modal editing is a weird historical contingency we have through sheer happenstance
Vim wants you to control, VSCode wants you to consume
Hillel Wayne · 2026-08-19 · via Computer Things

Newsletter updates were sporadic in July because of two weddings, two conferences (with two different talks!), and finishing Logic for Programmers. Huge thank you to everybody who bought a copy, as well as for your patience with the schedule. There's some podcast appearances, a conf talk, and a book sale at the end of this post.

Newsletter updates will be sporadic in August because I just started my Developer Educator job at Antithesis. I'll have less time to write because I'll be working 40 hour workweeks, about 8 hours of which being actual work and the other 32 being bashing my head against NixOS.

NixOS is the standard developer OS at the company. It's also a notoriously difficult distro to learn even for Linux heads, and I'm coming from Windows. The only way I am going to get anywhere is to go all in and commit fully to the NixOS philosophy.1 For one, I'm seeing how long I can last without my customary 2000-line Neovim config.

Which immediately raises the question as to why I have 2000 lines of Neovim config. It's because Vim2 (and Emacs) think of configuration in a very different way than more popular editors do.

Control and Consumption

Say we want to make ctrl+n to save the current file. In VSCode, you put this in keybindings.json:

[
  {
    "key": "ctrl+n",
    "command": "workbench.action.files.save"
  }
]

In Neovim, you put this in init.lua:

vim.keymap.set('n', '<c-n>', function() vim.cmd.write() end)

Now, a couple of differences to see. First, the VSCode example is invoking a fixed, built-in command, while Neovim can bind an arbitrary function. Second, in VSCode you edit a static configuration file with static data, while in Neovim you execute a command that edits the running editor state. In fact, it doesn't even need to be in a configuration file: you can add a new keymap directly from the command line. Though you'd probably instead do that command in the OG Vim way:

And that does something different than a function: it makes pressing ctrl+n mean "do whatever typing :w and pressing Enter would do." In default Vim that is the same as saving a file, but if you remapped : to o then it would instead do the equivalent of ow<cr>, which would type the character w on its own line. 3

In other words, Vim gives you incredible programmatic control over the state of the editor. Want to make typing ;r paste from the clipboard? Easy. Want different setting options in normal and insert mode? Go ahead. Want to make "writing a file" do something different during a full moon? You could if you want. 4

Now, you can do some amount of customization in VSCode, especially with multicommands, but for the majority of complex stuff you need to write a plugin. And making a plugin in VSCode is a much heavier process than making one in Neo/Vim. If you want to make a command that prints the word count, you have to 1) learn TypeScript, 2) scaffold a special VSCode extension project, 3) define a wordcount function, 4) register the mycode.wordcount command, 5) add mycode.wordcount as a contributes record in the extension manifest, 6) package or publish your extension, and 7) import the extension. It's very clear that the plugin system is not meant to let you tweak in a bit of functionality, but rather to let specialists produce complete plugins for other developers to consume. And since so much of the advanced functionality of VSCode is only possible through plugins, this limits the control the average user has over their environment.

Neovim also has plugins, but they can't do anything you couldn't already do in your default config. Admittedly, some bits of the APIs are meant specifically for plugin specialists, but they're still documented and available for your personal configuration. You never know what someone's gonna need!

In summary:

  • VSCode has a two-tier system, where plugin makers make plugins that users consume. The plugin has more power than the user. Most users aren't expected to make their own extensions.
  • Vim has a one-tier system: the user can do anything a plugin can. Everybody is always able to extend the system and have as much control as they want.

Most people should be consumers

Confession: this all is unintentionally a little ragebaity. "Consumer" is a dirty word in software. A consumer is somebody at the mercy of a producer's decisions. I think there's even a connotation of passiveness in being a consumer. It sort of starts leaning into a moral judgment: developers should use Neovim because it gives them control.

But, and this is intentionally a little ragebaity, it's the other way around. Most developers are better off sticking with the consumer model and only switching to a control-editor if they really, really want to. 5

First of all, learning to configure and extend Vim is hard. It took me a long time to get comfortable with even making basic scripts. And even if I'm comfortable hacking Vim, I still need to consume other people's plugins if I want a modern developer experience. I'm not writing my own treesitter integration from scratch! 6

Second, while the experience of developing plugins is worse on VSCode, the experience of consuming them is far, far better:

  • All plugins install, set up, and are used the same way. When I install a new plugin I don't have to spend ten minutes reading docs to get it working.
  • I can read a list of all the new commands, keybindings, and configuration options added by the extension. I can edit any configuration option in the same settings UI, which has features like global search and input validation.
  • I can enable and disable extensions without changing my startup scripts, and I can enable extensions for only specific workspaces.
  • If a plugin adds a keybinding that conflicts with my custom keybindings (or another plugin's keybindings), VSCode will tell me instead of silently clobbering the older one.
  • I can't break a plugin through a weird script I run at startup or by installing a different plugin.
  • A plugin can't break my startup.

These are all possible precisely because the VSCode plugin system is so heavyweight and inflexible and because everything is configured through static JSON files. Figuring out what configuration options a Neovim extension has is tantamount to solving the Halting Problem.

(The broader principle here is the ability-guarantee tradeoff. 7 A VSCode extension can do fewer things than a Vim extension can, and therefore we have more guarantees about what it actually does. Exploring the AGT is one of the running themes of Logic for Programmers.)

The consumption paradigm is worse than the control paradigm in a lot of ways but it's so much better in this one specific, extremely important way that it's the right choice for most developers. To some extent I wonder if preferring control is more a personality trait than a measured tradeoff. I'm unhappy when I can't tweak some software just to my liking, it just grates on me that something's off and can't be fixed. If tomorrow I woke up and was just not bothered by that, would I still prefer Neovim to VSCode? I dunno. Maybe I'll find out as part of The Nix Experience.


Now there's a third point in the design space I haven't talked about: what if the editor restricted both your control and consumption? Helix, for example, allows adding LSP servers and treesitter grammars but not any other kind of plugin.8 It also has a static and very limited configuration language. You can't even set different keybindings for different filetypes.

That seems crazy to me! But a lot of people seem to like it, and I've been interested in Kakoune-style modal editing for a while now. So now I'm running Helix as my main terminal editor. I don't know if I will stick with it; I feel like I'll eventually crave a more hackable editor. But at least then I'll be more comfortable with Nix before trying to import my thousands of lines of Neovim conf.


Appearances and stuff

Three this time:

Oh, also Amazon is selling Logic for Programmers for 15% off for some reason. I confirmed I get the same royalties either way, so hey, it's cheaper with no downside. I have no idea how long the sale will last.