diff --git a/.config/nvim/.nvimlog b/.config/nvim/.nvimlog index df078dc..da344ca 100644 --- a/.config/nvim/.nvimlog +++ b/.config/nvim/.nvimlog @@ -8,3 +8,4 @@ WRN 2026-08-28T16:41:19.378 ?.2 server_start:199: Failed to start server: WRN 2026-08-31T13:42:03.306 ?.2 server_start:199: Failed to start server: operation not permitted: /run/user/1000/nvim.2.0 WRN 2026-08-31T13:42:57.702 ?.2 server_start:199: Failed to start server: operation not permitted: /run/user/1000/nvim.2.0 WRN 2026-08-31T13:43:16.053 ?.2 server_start:199: Failed to start server: operation not permitted: /run/user/1000/nvim.2.0 +WRN 2026-09-01T13:41:43.821 ?.2 server_start:199: Failed to start server: operation not permitted: /run/user/1000/nvim.2.0 diff --git a/.config/nvim/lazy-lock.json b/.config/nvim/lazy-lock.json index 79878b7..fab9e75 100644 --- a/.config/nvim/lazy-lock.json +++ b/.config/nvim/lazy-lock.json @@ -28,7 +28,7 @@ "lualine.nvim": { "branch": "master", "commit": "221ce6b2d999187044529f49da6554a92f740a96" }, "mcphub.nvim": { "branch": "main", "commit": "7cd5db330f41b7bae02b2d6202218a061c3ebc1f" }, "mini.diff": { "branch": "main", "commit": "626b8a5b93874c4d05ca25aedec56cfff0b378fb" }, - "mini.nvim": { "branch": "main", "commit": "a311ed247d527db9592bb434356badc705363746" }, + "mini.nvim": { "branch": "main", "commit": "9d01f392b33fb2ba36fbc87fc0bf4453e63ffb0a" }, "noice.nvim": { "branch": "main", "commit": "7bfd942445fb63089b59f97ca487d605e715f155" }, "nui.nvim": { "branch": "main", "commit": "10fc361835c856ba4233ef5ea135b919bf3dce97" }, "nvim-autopairs": { "branch": "master", "commit": "430522f95fe4fb7c511ec64f8c1a90cc6a66c05c" }, @@ -36,7 +36,7 @@ "nvim-colorizer.lua": { "branch": "master", "commit": "a065833f35a3a7cc3ef137ac88b5381da2ba302e" }, "nvim-html-css": { "branch": "main", "commit": "3f246f6166e75fb8afc1866ce8f1e4cb8d95757a" }, "nvim-lint": { "branch": "master", "commit": "3d55c8f67c6ae5c15e1042571e107c7a3d5c5f4e" }, - "nvim-lspconfig": { "branch": "master", "commit": "16286347bdba1333c7d124d9de9fe6630731b2b2" }, + "nvim-lspconfig": { "branch": "master", "commit": "ee1e369181a9e64904cdd7b739e98c70778cfc71" }, "nvim-nio": { "branch": "master", "commit": "edcc181a875301dd21840189aa2f2f9ad69fc172" }, "nvim-treesitter": { "branch": "master", "commit": "cf12346a3414fa1b06af75c79faebe7f76df080a" }, "nvim-treesitter-context": { "branch": "master", "commit": "f3061339b8eaf9fda873600bc425b8d2d8502533" }, diff --git a/.config/nvim/lua/plugins/codecompanion.lua b/.config/nvim/lua/plugins/codecompanion.lua index 76aeb51..3ec851a 100644 --- a/.config/nvim/lua/plugins/codecompanion.lua +++ b/.config/nvim/lua/plugins/codecompanion.lua @@ -336,19 +336,19 @@ return { -- log_level = "TRACE", }, extensions = { - -- mcphub = { - -- callback = "mcphub.extensions.codecompanion", - -- opts = { - -- show_result_in_chat = true, -- Show the mcp tool result in the chat buffer - -- make_vars = true, -- make chat #variables from MCP server resources - -- make_slash_commands = true, -- make /slash_commands from MCP server prompts - -- }, - -- }, + mcphub = { + callback = "mcphub.extensions.codecompanion", + opts = { + show_result_in_chat = true, -- Show the mcp tool result in the chat buffer + make_vars = true, -- make chat #variables from MCP server resources + make_slash_commands = true, -- make /slash_commands from MCP server prompts + }, + }, }, memory = { opts = { chat = { - enabled = true, + enabled = false, }, }, }, @@ -365,8 +365,6 @@ return { "AGENT.md", "AGENTS.md", { path = "CLAUDE.md", parser = "claude" }, - { path = "CLAUDE.local.md", parser = "claude" }, - { path = "~/.claude/CLAUDE.md", parser = "claude" }, }, is_preset = true, }, diff --git a/.config/nvim/lua/plugins/lualine.lua b/.config/nvim/lua/plugins/lualine.lua index 448b6c1..8c96108 100644 --- a/.config/nvim/lua/plugins/lualine.lua +++ b/.config/nvim/lua/plugins/lualine.lua @@ -1,14 +1,49 @@ +local mcphub_spinner_frames = { "⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏" } + +local function mcphub_status() + if not vim.g.loaded_mcphub then + return "󰐻 -" + end + + local status = vim.g.mcphub_status or "stopped" + if status == "stopped" then + return "󰐻 -" + end + + if vim.g.mcphub_executing or status == "starting" or status == "restarting" then + local frame = math.floor(vim.uv.now() / 100) % #mcphub_spinner_frames + 1 + return "󰐻 " .. mcphub_spinner_frames[frame] + end + + return "󰐻 " .. (vim.g.mcphub_servers_count or 0) +end + +local function mcphub_color() + if not vim.g.loaded_mcphub then + return { fg = "#6c7086" } + end + + local status = vim.g.mcphub_status or "stopped" + if status == "ready" or status == "restarted" then + return { fg = "#50fa7b" } + elseif status == "starting" or status == "restarting" then + return { fg = "#ffb86c" } + end + + return { fg = "#ff5555" } +end + return { "nvim-lualine/lualine.nvim", dependencies = { "AndreM222/copilot-lualine", "nvim-tree/nvim-web-devicons", - "ravitemer/mcphub.nvim", }, config = function() require("lualine").setup({ options = { - theme = "catppuccin", + -- theme = "catppuccin", + theme = "auto", component_separators = { left = "", right = "" }, section_separators = { left = "", right = "" }, }, @@ -18,7 +53,7 @@ return { lualine_c = { "filename" }, lualine_x = { "searchcount", - require("mcphub.extensions.lualine"), + { mcphub_status, color = mcphub_color }, { "copilot", symbols = { diff --git a/.config/nvim/nvim-config-guide.html b/.config/nvim/nvim-config-guide.html new file mode 100644 index 0000000..2ede36e --- /dev/null +++ b/.config/nvim/nvim-config-guide.html @@ -0,0 +1,654 @@ + + + + + + + Neovim Config Field Manual + + + + + +
+ + +
+
+
Neovim configuration / annotated system map
+

Small core.
Deep tools.

+

A practical map of how this Lua configuration boots, where behavior belongs, and which plugin owns each editing concern.

+
+ 58 declared plugins + Lazy-loaded mappings + No LSP format fallback + 0 Luacheck warnings +
+
+ +
+
+
01

Boot sequence

+

init.lua is intentionally boring. It establishes Lazy first, then layers presentation, mappings, editor events, highlights, and one specialized LSP helper.

+
+
+
01

core.lazy

Bootstraps Lazy and loads core options before plugins.

+
02

plugins/*

Lazy discovers specs and installs handlers for events, commands, and keys.

+
03

colorscheme

Catppuccin Macchiato supplies the visual baseline.

+
04

core.keymaps

Core editing, LSP, commands, and group labels register.

+
05

autocmds

Editor-level reactions attach once through named augroups.

+
06

highlights

Small local highlight overrides apply after the theme.

+
07

Hyprland LSP

The file-pattern-specific helper starts only where relevant.

+
+
+ +
+
+
02

One owner per concern

+

Maintenance gets easier when two plugins do not compete for the same surface. Select a row to inspect the boundary.

+
+
+
+ + + + + + +
+
+
Deterministic output

Formatters only.

Conform runs explicit tools per filetype. Python prefers Ruff, with isort and Black as the fallback toolchain. LSP formatting is deliberately set to never, so a newly attached server cannot silently change save behavior.

+
Diagnostics after write

Lint without mutation.

nvim-lint runs once on BufWritePost. Ruff supplies Python diagnostics. Pydoclint and Codespell join only when their executables exist, avoiding noisy missing-tool warnings.

+
Insert-mode intelligence

Completion needs no shim.

nvim-cmp gathers sources and LuaSnip expands snippets. None-ls was not part of this path, so removing it does not remove completion.

+
Clear channel boundaries

Three surfaces, zero contention.

Snacks owns general notifications. Fidget owns LSP progress. Noice owns the command line and message history, with its notification forwarding and LSP progress disabled.

+
One tree

Explorer replaces two browsers.

<leader>fb and <leader>nt both open Snacks Explorer, preserving muscle memory while removing nvim-tree and Telescope file-browser.

+
Session-aware shells

Named tools stay alive.

ToggleTerm owns splits, tabs, floats, and named sessions for btop, IPython, iotop, Lazydocker, nvtop, and rmpc. Snacks Terminal remains explicitly disabled.

+
+
+
+ +
+
+
03

Keymaps follow ownership

+

The configuration uses two mapping paths. The deciding question is whether the mapping requires a plugin.

+
+
+

Core behavior

Editing motions, workspace operations, LSP calls, and local helper commands use vim.keymap.set inside lua/core/keymaps/.

+ +

Plugin behavior

Telescope, Snacks, CodeCompanion, images, Diffview, and terminals declare mappings in their Lazy keys tables. The mapping becomes the load trigger.

+
+
+
Core example

Direct and unsurprising

map("n", "<leader>ca", vim.lsp.buf.code_action, {
+	desc = "Code action",
+})
+
Plugin example

Mapping as load boundary

keys = {
+	{ "<leader>fb", function()
+		Snacks.explorer()
+	end, desc = "File browser" },
+}
+
+
which-key has one job: it labels prefix groups. It no longer converts mapping tables or acts as a second mapping registry.
+
+ +
+
+
04

Lazy is the seam

+

Every file in lua/plugins/ returns one plugin spec. The spec keeps the trigger, dependencies, mappings, options, and exceptional setup in one navigable place.

+
+
+
Prefer data

opts for ordinary setup

When a plugin follows require(module).setup(opts), its configuration stays declarative. Lazy can merge it and call setup at the correct time.

return {
+	"stevearc/conform.nvim",
+	opts = { -- formatter policy },
+}
+
Use code selectively

config for real orchestration

ToggleTerm needs named terminal objects and a terminal-buffer autocmd. That lifecycle is real behavior, so a focused config function is justified.

config = function(_, opts)
+	require("toggleterm").setup(opts)
+	-- create named sessions once
+end
+
+
Avoid eager requires: 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.
+
+ +
+
+
05

Complexity removed

+

The cleanup favors replacement over compatibility layers. Old aliases remain where useful, but dead modules and duplicate owners do not.

+
+
+
nvim-treeSnacks Explorer

One browser, two preserved entry mappings.

+
Telescope file-browserTelescope search

Search stays focused on pickers and discovery.

+
nvim-notifySnacks Notifier

General messages move to the plugin already loaded at startup.

+
none-lsConform + nvim-lint

Formatting, linting, and completion now have separate owners.

+
OpencodeCodeCompanion

One in-editor AI workflow remains, alongside Copilot completion.

+
converter modulesNative mapping APIs

Less indirection between a key and the behavior it invokes.

+
+
+ +
+
+
06

Maintenance loop

+

Run these from ~/.config/nvim. Each check covers a different failure class: style drift, static mistakes, or startup integration.

+
+
+
01stylua --check .
+
02luacheck .
+
03jq empty lazy-lock.json
+
04nvim --headless -i NONE -u ./init.lua '+qa'
+
+
Tool availability: optional linters should be conditional. The configuration registers Pydoclint and Codespell only when the corresponding executable is installed.
+
+ + +
+
+ + + +