<p><code>init.lua</code> is intentionally boring. It establishes Lazy first, then layers presentation, mappings, editor events, highlights, and one specialized LSP helper.</p>
<articleclass="boot-step"><spanclass="boot-index">01</span><h3>core.lazy</h3><p>Bootstraps Lazy and loads core options before plugins.</p></article>
<articleclass="boot-step"><spanclass="boot-index">02</span><h3>plugins/*</h3><p>Lazy discovers specs and installs handlers for events, commands, and keys.</p></article>
<articleclass="boot-step"><spanclass="boot-index">03</span><h3>colorscheme</h3><p>Catppuccin Macchiato supplies the visual baseline.</p></article>
<articleclass="boot-step"><spanclass="boot-index">04</span><h3>core.keymaps</h3><p>Core editing, LSP, commands, and group labels register.</p></article>
<articleclass="boot-step"><spanclass="boot-index">05</span><h3>autocmds</h3><p>Editor-level reactions attach once through named augroups.</p></article>
<articleclass="boot-step"><spanclass="boot-index">06</span><h3>highlights</h3><p>Small local highlight overrides apply after the theme.</p></article>
<articleclass="boot-step"><spanclass="boot-index">07</span><h3>Hyprland LSP</h3><p>The file-pattern-specific helper starts only where relevant.</p></article>
</div>
</section>
<sectionclass="section"id="ownership">
<divclass="section-head reveal">
<div><spanclass="section-number">02</span><h2>One owner per concern</h2></div>
<p>Maintenance gets easier when two plugins do not compete for the same surface. Select a row to inspect the boundary.</p>
<divclass="owner"id="owner-lint"role="tab"tabindex="-1"aria-selected="false"aria-controls="detail-lint"data-owner="lint"><spanclass="owner-key">L</span><div><strong>nvim-lint</strong><span>diagnostics on save</span></div></div>
<divclass="active"id="detail-format"role="tabpanel"aria-labelledby="owner-format"data-detail="format"><spanclass="kicker">Deterministic output</span><h3>Formatters only.</h3><p>Conform runs explicit tools per filetype. Python prefers Ruff, with isort and Black as the fallback toolchain. LSP formatting is deliberately set to <code>never</code>, so a newly attached server cannot silently change save behavior.</p></div>
<divid="detail-lint"role="tabpanel"aria-labelledby="owner-lint"data-detail="lint"><spanclass="kicker">Diagnostics after write</span><h3>Lint without mutation.</h3><p>nvim-lint runs once on <code>BufWritePost</code>. Ruff supplies Python diagnostics. Pydoclint and Codespell join only when their executables exist, avoiding noisy missing-tool warnings.</p></div>
<divid="detail-complete"role="tabpanel"aria-labelledby="owner-complete"data-detail="complete"><spanclass="kicker">Insert-mode intelligence</span><h3>Completion needs no shim.</h3><p>nvim-cmp gathers sources and LuaSnip expands snippets. None-ls was not part of this path, so removing it does not remove completion.</p></div>
<divid="detail-notify"role="tabpanel"aria-labelledby="owner-notify"data-detail="notify"><spanclass="kicker">Clear channel boundaries</span><h3>Three surfaces, zero contention.</h3><p>Snacks owns general notifications. Fidget owns LSP progress. Noice owns the command line and message history, with its notification forwarding and LSP progress disabled.</p></div>
<divid="detail-files"role="tabpanel"aria-labelledby="owner-files"data-detail="files"><spanclass="kicker">One tree</span><h3>Explorer replaces two browsers.</h3><p><code><leader>fb</code> and <code><leader>nt</code> both open Snacks Explorer, preserving muscle memory while removing nvim-tree and Telescope file-browser.</p></div>
<divid="detail-terminal"role="tabpanel"aria-labelledby="owner-terminal"data-detail="terminal"><spanclass="kicker">Session-aware shells</span><h3>Named tools stay alive.</h3><p>ToggleTerm owns splits, tabs, floats, and named sessions for btop, IPython, iotop, Lazydocker, nvtop, and rmpc. Snacks Terminal remains explicitly disabled.</p></div>
<p>The configuration uses two mapping paths. The deciding question is whether the mapping requires a plugin.</p>
</div>
<divclass="mapping-rule reveal">
<divclass="rule-box"><h3>Core behavior</h3><p>Editing motions, workspace operations, LSP calls, and local helper commands use <code>vim.keymap.set</code> inside <code>lua/core/keymaps/</code>.</p></div>
<divclass="rule-arrow"aria-hidden="true">◆</div>
<divclass="rule-box"><h3>Plugin behavior</h3><p>Telescope, Snacks, CodeCompanion, images, Diffview, and terminals declare mappings in their Lazy <code>keys</code> tables. The mapping becomes the load trigger.</p></div>
</div>
<divclass="split reveal"style="margin-top: 1px">
<articleclass="panel"><spanclass="kicker">Core example</span><h3>Direct and unsurprising</h3><pre><spanclass="lua-key">map</span>(<spanclass="lua-str">"n"</span>, <spanclass="lua-str">"<leader>ca"</span>, vim.lsp.buf.code_action, {
desc = <spanclass="lua-str">"Code action"</span>,
})</pre></article>
<articleclass="panel"><spanclass="kicker">Plugin example</span><h3>Mapping as load boundary</h3><pre>keys = {
<divclass="callout reveal"><strong>which-key has one job:</strong> it labels prefix groups. It no longer converts mapping tables or acts as a second mapping registry.</div>
</section>
<sectionclass="section"id="plugins">
<divclass="section-head reveal">
<div><spanclass="section-number">04</span><h2>Lazy is the seam</h2></div>
<p>Every file in <code>lua/plugins/</code> returns one plugin spec. The spec keeps the trigger, dependencies, mappings, options, and exceptional setup in one navigable place.</p>
</div>
<divclass="split reveal">
<articleclass="panel"><spanclass="kicker">Prefer data</span><h3><code>opts</code> for ordinary setup</h3><p>When a plugin follows <code>require(module).setup(opts)</code>, its configuration stays declarative. Lazy can merge it and call setup at the correct time.</p><pre><spanclass="lua-key">return</span> {
<articleclass="panel"><spanclass="kicker">Use code selectively</span><h3><code>config</code> for real orchestration</h3><p>ToggleTerm needs named terminal objects and a terminal-buffer autocmd. That lifecycle is real behavior, so a focused <code>config</code> function is justified.</p><pre>config = <spanclass="lua-key">function</span>(_, opts)
<spanclass="lua-note">-- create named sessions once</span>
<spanclass="lua-key">end</span></pre></article>
</div>
<divclass="callout reveal"><strong>Avoid eager requires:</strong> do not call plugin modules while Lua is merely building a spec table. Wrap callback references in a function so Lazy can finish registering the plugin before it loads.</div>
<divclass="callout reveal"><strong>Tool availability:</strong> optional linters should be conditional. The configuration registers Pydoclint and Codespell only when the corresponding executable is installed.</div>
</section>
<footer><span>Neovim Config Field Manual</span><span>Small core / explicit ownership / load on demand</span></footer>
# Keep the device on A2DP/AAC and avoid restoring stale device state.
# Keep the device on A2DP/AAC and restore its last volume.
wireplumber.settings = {
bluetooth.autoswitch-to-headset-profile = false
device.restore-profile = false
device.restore-routes = false
device.restore-routes = true
}
monitor.bluez.rules = [
{
matches = [
{
device.name = "bluez_card.18_3F_70_4E_02_CC"
device.description = "~AirPods.*"
}
]
actions = {
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.