<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Unformed Delta - wiki</title>
    <description>A place to collect the things I learn, figure out, or find interesting.
</description>
    <link>https://unformeddelta.wiki/</link>
    <atom:link href="https://unformeddelta.wiki/feed/wiki.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sat, 09 May 2026 14:44:19 +0000</pubDate>
    <lastBuildDate>Sat, 09 May 2026 14:44:19 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
    <item>
      <title>My Neovim configuration</title>
      <description>&lt;p&gt;I use Neovim for 95%+ of my writing, both prose and code. I originally picked Vim over Emacs because I liked its modal text editing. Over the following years I’ve honed it to my preferences, building up over ~4000 lines of configuration. I’ve flirted with switching to Emacs with evil-mode for a better plugin ecosystem, but Vim is too deeply engraved in my muscle memory to move away from.&lt;/p&gt;

&lt;h2 id=&quot;lua-vs-vimscript&quot;&gt;Lua vs Vimscript&lt;/h2&gt;
&lt;p&gt;I don’t have a strong preference for Lua/Vimscript. Historically, Vimscript was the only language for configuring Vim&lt;sup id=&quot;fnref:which-are-bad&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:which-are-bad&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; . I generally assume that I will always use Neovim nowadays. Neovim makes Lua a first class language for configuring Vim. In fact, in addition to bridging all of Vim’s APIs to Lua, new APIs (such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vim.lsp&lt;/code&gt;) are often only offered through Lua.&lt;/p&gt;

&lt;p&gt;Rewriting all of my configuration in Lua just to lose support for Vim completely seems like a waste of time, so I still keep a lot of my configuration in Vimscript. I tend to prefer Vimscript’s syntax for &lt;a href=&quot;https://github.com/lehmacdj/.dotfiles/blob/623ba890da5afff964d72010ab28214edf53e4b7/nvim.symconfig/init.vim#L241-L242&quot;&gt;mappings&lt;/a&gt; and &lt;a href=&quot;https://github.com/lehmacdj/.dotfiles/blob/623ba890da5afff964d72010ab28214edf53e4b7/nvim.symconfig/init.vim#L214-L218&quot;&gt;autocommands&lt;/a&gt; to &lt;a href=&quot;https://github.com/lehmacdj/.dotfiles/blob/af7972a429a12a86649b5671c66a4ecf267b09de/nvim.symconfig/plugin/lsp.lua#L46-L48&quot;&gt;Lua’s&lt;/a&gt; anyways. Lua’s feels a little bit too verbose, and is harder to understand quickly in my opinion.&lt;/p&gt;

&lt;p&gt;Neovim makes it very easy to mix Lua and Vimscript, which makes it possible to maintain interoperability even while maintaining configuration in both.&lt;/p&gt;

&lt;h2 id=&quot;escape-key&quot;&gt;Escape key&lt;/h2&gt;
&lt;p&gt;Because the escape key is far in the top left corner of modern keyboards, mapping &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jj&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jk&lt;/code&gt; to escape in insert mode is fairly common. I used to do this. At some point I learned that Vim and most Vim plugins for other text editors treat &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;C-[&amp;gt;&lt;/code&gt; as escape. Rebinding caps lock to control system wide, made it possible to press &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;C-[&amp;gt;&lt;/code&gt; with my two pinkies simultaneously. An escape key mapping was previously the only configuration I truly couldn’t do without so this has the added benefit of letting me use Vim-mode plugins in other editors (or Vim itself through SSH) well enough without needing to configure them.&lt;/p&gt;

&lt;h2 id=&quot;modularization&quot;&gt;Modularization&lt;/h2&gt;
&lt;p&gt;Because my config has grown quite large, I need to keep it modularized for it to stay maintainable.&lt;/p&gt;

&lt;p&gt;Mostly I rely on the runtime directory structure which allows loading a lot of files flexibly:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init.vim&lt;/code&gt; has logic that needs to run before other configuration, plus a bunch of stuff that I’ve been too lazy to move elsewhere&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;plugins.vim&lt;/code&gt; is sourced from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;init.vim&lt;/code&gt; and loads plugins. I have this separated out because I use a lot of plugins&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ftsyntax&lt;/code&gt; directories for autocommands improving file type detection, or adding new&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ftplugin/after&lt;/code&gt; directories house language specific configuration to prevent needing to define autocommands for them&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;autoload&lt;/code&gt; directories store “library” functions that I use from other pieces of my configuration&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lua/my&lt;/code&gt; modules serve the same purpose, but for Lua code&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;plugin&lt;/code&gt; directories for configuration insensitive to loading order&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;plugins&quot;&gt;Plugins&lt;/h2&gt;
&lt;p&gt;I still use vim-plug to manage my plugins because it works well enough, and well written plugins lazy load by design, thus not requiring anything fancier.&lt;/p&gt;

&lt;p&gt;I’m a heavy plugin user so I’ll only go through my favorite plugins. The most notable category is plugins that add generic cross language features to the editor without conflicting with default keybindings:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tpope/vim-repeat&lt;/code&gt; makes it possible to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.&lt;/code&gt; with custom actions provided by other plugins. This should really just be a built in Vim feature.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tpope/vim-sleuth&lt;/code&gt; makes indentation behave sanely by default.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tpope/vim-surround&lt;/code&gt; adds a truly essential &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ys&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cs&lt;/code&gt;/&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ds&lt;/code&gt; text editing verbs for adding/changing/deleting surrounding text&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tommcdo/vim-exchange&lt;/code&gt; provides a very useful &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cx&lt;/code&gt; text editing verb for swapping text&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wellle/targets.vim&lt;/code&gt; adds extra text objects (e.g. for function arguments) and makes existing text objects more flexible (e.g. selecting the next instance of a text object if you aren’t already inside of it)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;overcache/NeoSolarized&lt;/code&gt; for my color scheme because it’s the most modern true color Solarized color scheme that I could find. I use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvim-lualine/lualine&lt;/code&gt; + &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvim-tree/nvim-web-devicons&lt;/code&gt; to make the UI a bit prettier.&lt;/p&gt;

&lt;p&gt;For more IDE like features, I mostly rely on language servers, but some extra support is provided by plugins.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hrsh7th/nvim-cmp&lt;/code&gt; for autocomplete though I’m considering switching off this because it is now unmaintained&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LuaSnip&lt;/code&gt; for snippets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other than that, there’s pretty much just a bunch of syntax plugins.&lt;/p&gt;

&lt;p&gt;I’ve also factored bits of my config as plugins (e.g. &lt;a href=&quot;/Rna31XL7OHqU/vim-magic-link-paste&quot;&gt;vim-magic-link-paste&lt;/a&gt;) plus a syntax plugin for moss-lang. A way to keep it easy to edit these even though they are no longer in my dotfiles repo is to branch on whether the repository exists on my computer:&lt;/p&gt;
&lt;div class=&quot;language-vim highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;isdirectory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;$HOME&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;/src/vim-magic-link-paste&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  Plug $HOME&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;/src/vim-magic-link-paste&apos;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
  Plug &lt;span class=&quot;s1&quot;&gt;&apos;lehmacdj/vim-magic-link-paste&apos;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;endif&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This way, vim-plug won’t clone them, and I can edit the source and have it stay up to date automatically.&lt;/p&gt;

&lt;h2 id=&quot;making-changes-to-configuration&quot;&gt;Making changes to configuration&lt;/h2&gt;
&lt;p&gt;I find being able to quickly navigate to a specific bit of configuration that I want to tweak important so that I’m able to fix problems / add new configuration without breaking my flow.&lt;/p&gt;

&lt;p&gt;I use mappings that open up a configuration file in a split:&lt;/p&gt;
&lt;div class=&quot;language-vim highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;&quot; Edit vimrc&lt;/span&gt;
nnoremap &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;Leader&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;ev &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;Cmd&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;split&lt;/span&gt; $MYVIMRC&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;CR&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;&quot; Edit plugins&lt;/span&gt;
nnoremap &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;Leader&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ep&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;Cmd&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;split&lt;/span&gt; $VIMHOME/plugins&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;vim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;CR&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;My favorite is my one for editing language specific tweaks, it directly opens up the appropriate file for the current file type:&lt;/p&gt;
&lt;div class=&quot;language-vim highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;&quot; Edit filetype file&lt;/span&gt;
nnoremap &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;expr&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;Leader&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ef&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&amp;lt;Cmd&amp;gt;split &apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;$VIMHOME&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;/after/ftplugin/&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&amp;amp;&lt;span class=&quot;k&quot;&gt;filetype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;.vim&amp;lt;CR&amp;gt;&apos;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;language-specific-tweaks&quot;&gt;Language specific tweaks&lt;/h2&gt;
&lt;p&gt;I most frequently edit my language specific configuration when I’m learning a language, or using a language I haven’t edited in a while. Most commonly, language specific configuration is overrides for my global vim config like &lt;a href=&quot;https://github.com/lehmacdj/.dotfiles/blob/d360d71f7811664994519ca10f18254743364c2e/nvim.symconfig/after/ftplugin/make.vim#L1-L3&quot;&gt;not converting tabs into spaces for Makefile&lt;/a&gt; or &lt;a href=&quot;https://github.com/lehmacdj/.dotfiles/blob/9b6a637f5c17bb9f9895f8fe03d96d4be480a8b4/nvim.symconfig/after/ftplugin/markdown.vim#L39&quot;&gt;setting up soft wrapping for Markdown&lt;/a&gt;. I also include custom keybindings that are only relevant for particular file types, like &lt;a href=&quot;https://github.com/lehmacdj/.dotfiles/blob/9b6a637f5c17bb9f9895f8fe03d96d4be480a8b4/nvim.symconfig/after/ftplugin/markdown.vim#L67-L68&quot;&gt;publishing a note from my wiki&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;wiki-specific-stuff&quot;&gt;Wiki specific stuff&lt;/h2&gt;
&lt;p&gt;For my notes specifically I have a &lt;a href=&quot;https://github.com/lehmacdj/wiki-language-server&quot;&gt;custom language server&lt;/a&gt; that I use providing autocomplete + title transclusion from random ids + go to definition for navigating between notes. I rely heavily on conceal to keep markdown syntax hidden while reading notes in Neovim.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:which-are-bad&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;There also were remote plugins. But they require installing language runtimes, and have a more limited API than exposed through Vimscript. &lt;a href=&quot;#fnref:which-are-bad&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 23 Apr 2026 06:02:00 +0000</pubDate>
      <link>https://unformeddelta.wiki/LylN8Ju8BGfr/my-neovim-configuration</link>
      <guid isPermaLink="true">https://unformeddelta.wiki/LylN8Ju8BGfr/my-neovim-configuration</guid>
      
      <category>vim</category>
      
      <category>recommended</category>
      
      <category>inkhaven</category>
      
      <category>wiki</category>
      
    </item>
    
    <item>
      <title>vim-magic-link-paste</title>
      <description>&lt;p&gt;I’m releasing &lt;a href=&quot;https://github.com/lehmacdj/vim-magic-link-paste&quot;&gt;vim-magic-link-paste&lt;/a&gt; today. When pasting a link over visually selected markdown text it creates markdown syntax for a link. See the video for an example of what the plugin can do:&lt;/p&gt;
&lt;video width=&quot;400&quot; controls=&quot;&quot; alt=&quot;A video that demos using the plugin in vim&quot;&gt;
  &lt;source src=&quot;/images/vim-magic-link-paste-demo.mov&quot; /&gt;
&lt;/video&gt;

&lt;p&gt;I originally built this functionality because I wanted a GitHub/Slack/Discord-like experience while adding links to my notes/blog posts. I’ve found it to be a huge quality of life improvement, and it encourages me to add more links.&lt;/p&gt;

&lt;p&gt;Though already having the functionality working made it pretty easy to package this as a plugin, the work to “productionize” the plugin was more significant than I expected:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;My original mapping depended on &lt;a href=&quot;https://github.com/tpope/vim-surround&quot;&gt;vim-surround&lt;/a&gt; using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;S]&lt;/code&gt; to surround the visual selection with square brackets. Replacing this was pretty easy. The marks &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;`&amp;lt;&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;`&amp;gt;&lt;/code&gt; indicate the beginning/end of the most recent visual selection. It’s easy to jump to the end of the visual selection then insert &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;]&lt;/code&gt; followed by jumping to the beginning of the visual selection and inserting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;I wrote a vim help file, to provide &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:h&lt;/code&gt; documentation for my plugin. Conveniently, you can get example syntax for any help page just by doing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set conceallevel=0&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;A little extra boilerplate ended up being to make sure the plugin doesn’t load twice + offer a way for users to opt out of key mappings.&lt;/li&gt;
  &lt;li&gt;Supporting &lt;a href=&quot;https://github.com/tpope/vim-repeat&quot;&gt;vim-repeat&lt;/a&gt; ended up being a bit trickier than I expected.&lt;/li&gt;
&lt;/ul&gt;
</description>
      <pubDate>Mon, 08 Sep 2025 05:30:00 +0000</pubDate>
      <link>https://unformeddelta.wiki/Rna31XL7OHqU/vim-magic-link-paste</link>
      <guid isPermaLink="true">https://unformeddelta.wiki/Rna31XL7OHqU/vim-magic-link-paste</guid>
      
      <category>recommended</category>
      
      <category>vim</category>
      
      <category>wiki</category>
      
    </item>
    
  </channel>
</rss>
