<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Neovim on Spoljarevic's Knowledgebase</title><link>https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/</link><description>Recent content in Neovim on Spoljarevic's Knowledgebase</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Sat, 15 Aug 2026 09:32:08 +0200</lastBuildDate><atom:link href="https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/index.xml" rel="self" type="application/rss+xml"/><item><title>Introduction</title><link>https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/Introduction/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/Introduction/</guid><description>&lt;h2 id="what-is-lazynvim"&gt;What is lazy.nvim?&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;a href="https://github.com/folke/lazy.nvim"&gt;lazy.nvim&lt;/a&gt; is a plugin manager for Neovim. It handles cloning,&#10;updating, and lazy-loading plugins from a set of declarative &amp;ldquo;specs&amp;rdquo; — Lua tables that say which plugin to&#10;install, what triggers it to load (a command, a keymap, a filetype, an event), and how to configure it once&#10;loaded.&lt;/p&gt;&#10;&lt;h2 id="what-this-is"&gt;What this is&#10;&lt;/h2&gt;&#10;&lt;p&gt;A Neovim configuration written entirely from scratch on top of &lt;code&gt;lazy.nvim&lt;/code&gt; — every option, keymap, and&#10;plugin spec here was written by hand, plugin by plugin. It is &lt;strong&gt;not&lt;/strong&gt; the &lt;a href="https://www.lazyvim.org/"&gt;LazyVim&lt;/a&gt;&#10;distribution, and doesn&amp;rsquo;t depend on it. Distributions like LazyVim or kickstart.nvim ship pre-built,&#10;opinionated defaults (LSP presets via &lt;code&gt;nvim-lspconfig&lt;/code&gt;&amp;rsquo;s setup functions, a formatter framework, a fixed&#10;plugin set); this config instead wires each piece directly, which means more to write, but nothing hidden&#10;behind a distribution&amp;rsquo;s abstractions.&lt;/p&gt;</description></item><item><title>Usage</title><link>https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/Usage/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/Usage/</guid><description>&lt;h2 id="deployment"&gt;Deployment&#10;&lt;/h2&gt;&#10;&lt;p&gt;There&amp;rsquo;s no separate install step for this config specifically — it&amp;rsquo;s deployed as part of the&#10;&lt;a href="https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/"&gt;Dotfiles&lt;/a&gt; monorepo. &lt;code&gt;~/.config&lt;/code&gt; is a symlink to the root of that repository, so &lt;code&gt;nvim/&lt;/code&gt; inside it&#10;automatically becomes &lt;code&gt;~/.config/nvim&lt;/code&gt;, which is where Neovim looks for its config by default.&lt;/p&gt;&#10;&lt;div class="td-callout td-callout--note" role="note"&gt;&#10; &lt;div class="td-callout__title"&gt;&lt;i class="td-callout__icon fa-solid fa-circle-info" aria-hidden="true"&gt;&lt;/i&gt;&lt;span class="td-callout__label"&gt;Note&lt;/span&gt;&lt;/div&gt;&#10; &lt;div class="td-callout__body"&gt;&#10;&lt;p&gt;This means editing &lt;code&gt;~/.config/nvim/lua/plugins/foo.lua&lt;/code&gt; and editing this repo&amp;rsquo;s &lt;code&gt;nvim/lua/plugins/foo.lua&lt;/code&gt;&#10;are the same file.&lt;/p&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&lt;h2 id="first-launch"&gt;First launch&#10;&lt;/h2&gt;&#10;&lt;div class="td-code td-code--untitled" id="td-code-7e57618a-fence-0" data-td-code data-td-code-auto-id&#10; data-td-language="sh" data-td-line-count="1"&gt;&#10; &lt;div class="td-code__viewport" id="td-code-7e57618a-fence-0-viewport" data-td-code-viewport&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;nvim&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;On the very first run, &lt;code&gt;lua/config/lazy.lua&lt;/code&gt; detects that &lt;code&gt;lazy.nvim&lt;/code&gt; itself isn&amp;rsquo;t installed yet, clones it&#10;into Neovim&amp;rsquo;s data directory, and then installs every plugin declared under &lt;code&gt;lua/plugins/*.lua&lt;/code&gt;. Subsequent&#10;launches just load already-installed plugins.&lt;/p&gt;</description></item><item><title>Code Explanation</title><link>https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/Code-Explanation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/Code-Explanation/</guid><description>&lt;h2 id="load-order"&gt;Load order&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;init.lua&lt;/code&gt; is four requires, executed in order:&lt;/p&gt;&#10;&lt;div class="td-code td-code--untitled" id="td-code-6d9202fb-fence-0" data-td-code data-td-code-auto-id&#10; data-td-language="lua" data-td-line-count="4"&gt;&#10; &lt;div class="td-code__viewport" id="td-code-6d9202fb-fence-0-viewport" data-td-code-viewport&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-lua" data-lang="lua"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;config.options&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;config.lazy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;config.keymaps&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;config.autocmds&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;&lt;code&gt;config/options.lua&lt;/code&gt;&lt;/strong&gt; — plain &lt;code&gt;vim.o.*&lt;/code&gt; settings (line numbers, relative numbers, mouse support,&#10;split direction, 2-space indentation, etc). No plugins involved.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;&lt;code&gt;config/lazy.lua&lt;/code&gt;&lt;/strong&gt; — bootstraps &lt;code&gt;lazy.nvim&lt;/code&gt; itself: if it isn&amp;rsquo;t already cloned into Neovim&amp;rsquo;s data&#10;directory, &lt;code&gt;git clone&lt;/code&gt;s it, prepends it to the runtimepath, then calls&#10;&lt;code&gt;require(&amp;quot;lazy&amp;quot;).setup(&amp;quot;plugins&amp;quot;, { change_detection = { notify = false } })&lt;/code&gt;. That call auto-discovers&#10;and loads every spec file under &lt;code&gt;lua/plugins/*.lua&lt;/code&gt; — adding a new plugin is just adding a new file&#10;there, no manual registration step.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;&lt;code&gt;config/keymaps.lua&lt;/code&gt;&lt;/strong&gt; — global keymaps, centralized here rather than scattered per-plugin file (see&#10;&lt;a href="https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/Usage/"&gt;Usage&lt;/a&gt; for the full table).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;&lt;code&gt;config/autocmds.lua&lt;/code&gt;&lt;/strong&gt; — currently just the format-on-save autocmd.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="plugin-spec-files"&gt;Plugin spec files&#10;&lt;/h2&gt;&#10;&lt;p&gt;Each file under &lt;code&gt;lua/plugins/&lt;/code&gt; returns a &lt;code&gt;lazy.nvim&lt;/code&gt; spec table (or a list of tables), and filenames map&#10;roughly 1:1 to the plugin they configure:&lt;/p&gt;</description></item><item><title>FAQ</title><link>https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/FAQ/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/FAQ/</guid><description>&lt;h3 id="why-not-just-use-lazyvim-or-kickstartnvim"&gt;Why not just use LazyVim or kickstart.nvim?&#10;&lt;/h3&gt;&#10;&lt;p&gt;This config predates/deliberately avoids adopting a distribution. Writing every option, keymap, and plugin&#10;spec by hand keeps each piece traceable to a single file instead of hidden behind a distribution&amp;rsquo;s&#10;abstractions and defaults — at the cost of not getting features &amp;ldquo;for free.&amp;rdquo; See&#10;&lt;a href="https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/Introduction/"&gt;Introduction&lt;/a&gt; for the full reasoning.&lt;/p&gt;&#10;&lt;h3 id="why-hand-roll-lsp-instead-of-using-nvim-lspconfigs-setup-presets"&gt;Why hand-roll LSP instead of using &lt;code&gt;nvim-lspconfig&lt;/code&gt;&amp;rsquo;s &lt;code&gt;setup{}&lt;/code&gt; presets?&#10;&lt;/h3&gt;&#10;&lt;p&gt;Same reasoning as above, applied specifically to LSP: &lt;code&gt;lua/plugins/lsp.lua&lt;/code&gt; calls &lt;code&gt;vim.lsp.start()&lt;/code&gt;&#10;directly through a small &lt;code&gt;setup_lsp()&lt;/code&gt; helper instead of &lt;code&gt;require(&amp;quot;lspconfig&amp;quot;).&amp;lt;server&amp;gt;.setup{}&lt;/code&gt;. It also&#10;means the executable-existence guard (&lt;code&gt;vim.fn.executable(...)&lt;/code&gt;) is explicit and visible, rather than&#10;depending on &lt;code&gt;nvim-lspconfig&lt;/code&gt;&amp;rsquo;s own defaults. See &lt;a href="https://kb-migration.spoljarevic.sh/Other-Repos/Dotfiles/Neovim/Code-Explanation/"&gt;Code Explanation&lt;/a&gt; for the code.&lt;/p&gt;</description></item></channel></rss>