Skip to content

fix(nvim): statusline blanking, visual git staging, node provider, gsn#257

Merged
Gerrrt merged 2 commits into
mainfrom
nvim-statusline-gitsigns-provider-fixes
Jul 20, 2026
Merged

fix(nvim): statusline blanking, visual git staging, node provider, gsn#257
Gerrrt merged 2 commits into
mainfrom
nvim-statusline-gitsigns-provider-fixes

Conversation

@Gerrrt

@Gerrrt Gerrrt commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Second review pass over nvim/. Four defects, each verified empirically rather than by inspection.

1. Focusing the file tree blanked the entire statusline

plugins/lualine-nvim.lua set both:

disabled_filetypes = { statusline = { "NvimTree" } },   -- :182
extensions = { "nvim-tree", "lazy", "quickfix", ... },  -- :258

lualine evaluates disabled_filetypes and return nils before it consults extensions (lualine.nvim/lua/lualine.lua:298-306). So the nvim-tree extension was permanently unreachable — and since globalstatus = true means one shared bar, that nil blanked the statusline for every window whenever the tree held focus.

before:  laststatus=3   ft=NvimTree -> lualine.statusline() = nil
after:   laststatus=3   ft=NvimTree -> renders, len=81

Dropped the disable, kept the extension. Setting both is strictly worse than either.

2. Visual-mode git staging silently staged the whole hunk

<leader>gs / <leader>gr were mapped in { "n", "v" } to bare gs.stage_hunk / gs.reset_hunk. But range is the first parameter of both (gitsigns.nvim/lua/gitsigns/actions.lua:288, :376), and a Lua keymap rhs is invoked with no arguments — so range was always nil and gitsigns operated on the whole hunk under the cursor. Partial-hunk staging, the only reason to map visual mode, never happened. Nothing reads the visual selection implicitly; only the :Gitsigns command wrapper populates range, from command modifiers.

Normal and visual are now separate mappings, the visual pair passing { vim.fn.line("."), vim.fn.line("v") } (upstream's documented form) and bound to x rather than v so it does not also fire in select-mode.

Verified end to end in a real repo — staging lines 2-3 of a 3-line hunk:

@@ -1,5 +1,5 @@
 a
-b
-c
+CHANGED1
+CHANGED2
 d          <- line 4 (CHANGED3) correctly left unstaged
 e

3. The Node.js provider was the only health warning, and nothing could reach it

Its sole consumers are remote plugins — but config/lazy.lua disables the rplugin manifest loader, no installed plugin ships a manifest, and nothing references node_host. It was unreachable while emitting a permanent :checkhealth WARNING.

:checkhealth is now 0 errors, 0 warnings across every section.

The python3 provider is explicitly left enabled and documented as load-bearing: vimade probes has('python3') (vimade/autoload/vimade.vim:80) and selects a python renderer when present. Disabling it would silently downgrade a plugin in use.

4. gsn never existed

plugins/mini-nvim.lua passed update_n_lines = "gsn" in mini.surround's mappings, but that is not a key in its schema (add/delete/find/find_left/highlight/replace/suffix_last/suffix_next). Unknown keys are accepted silently — setup() returned OK and no mapping was created, while every other gs* map did exist. Mapped explicitly, as upstream's own docs prescribe (mini/surround.lua:909).

Validation

Check Result
luacheck lua init.lua 0 warnings / 0 errors, 86 files
nvim --headless -c 'qa!' exit 0, no stderr
:checkhealth (all sections) 0 errors, 0 warnings
make audit 222 pass / 0 fail

One audit check skipped (yaml parse — PyYAML not importable); environmental and pre-existing.

Deliberately not in this PR

A measured non-finding worth recording: nvim-lint.lua re-walks 12 eslint filenames upward on every InsertLeave with no cache. That sounds alarming, but measured worst-case (no config, 10 levels to /) it is 0.314 ms per call — imperceptible. Worth caching in vim.b[buf] for tidiness, not worth calling a performance bug.

Also deferred: a batch of dead-config/style items (inert bufferline hover.reveal, legacy adaptive_size key, a backwards fidget winblend comment, separator = nil no-op, redundant conform config), and the cheatsheet's completeness gaps — it claims to list every binding but has no Completion card at all, and no mini.move row.

🤖 Generated with Claude Code

https://claude.ai/code/session_018wpwbjkGJKPFgvBFEKsFWE

Four defects from a second review pass, each verified empirically.

Focusing the file tree blanked the whole statusline. lualine-nvim.lua set both
disabled_filetypes = { statusline = { "NvimTree" } } and
extensions = { "nvim-tree", ... }. lualine evaluates disabled_filetypes and
returns nil BEFORE consulting extensions (lualine.nvim/lua/lualine.lua:298-306),
so the nvim-tree extension was permanently unreachable — and with
globalstatus = true there is one shared bar, so that nil blanked the statusline
for every window whenever the tree held focus. Dropped the disable, kept the
extension. Verified: ft=NvimTree returned nil before, renders 81 cells now.

Visual-mode git staging silently staged the entire hunk. <leader>gs/<leader>gr
were mapped in { "n", "v" } to bare gs.stage_hunk/gs.reset_hunk, but range is
the FIRST parameter of both (gitsigns actions.lua:288, :376) and a Lua keymap
rhs is invoked with no arguments — so range was always nil and partial-hunk
staging, the only reason to map visual mode, never happened. Normal and visual
are now separate mappings; the visual pair passes { line("."), line("v") }
(upstream's documented form) and binds to x rather than v so it does not also
fire in select-mode. Verified end to end in a real repo: staging lines 2-3 of a
3-line hunk staged exactly those two and left the third unstaged.

The Node.js provider was the config's only health warning, and nothing could
reach it: its sole consumers are remote plugins, config/lazy.lua disables the
rplugin manifest loader, no installed plugin ships a manifest, and nothing
references node_host. Disabled. :checkhealth is now 0 errors / 0 warnings
across every section. python3 is explicitly left enabled and documented as
load-bearing — vimade probes has('python3') and picks a python renderer.

gsn never existed. mini-nvim.lua passed update_n_lines = "gsn" in
mini.surround's mappings, but that is not a key in its schema and unknown keys
are accepted silently: setup returned OK, no mapping was created, while every
other gs* map did exist. Mapped explicitly as upstream's docs prescribe.

Validated: luacheck 0/0 across 86 files, clean headless boot, checkhealth
0 errors / 0 warnings, make audit 222 pass / 0 fail.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018wpwbjkGJKPFgvBFEKsFWE
Copilot AI review requested due to automatic review settings July 20, 2026 13:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes four Neovim configuration defects affecting statusline rendering, git hunk operations, provider health, and surround mappings.

Changes:

  • Restores NvimTree statusline rendering and correct visual-range git staging/reset.
  • Adds the missing gsn surround mapping.
  • Disables the unused Node provider and documents all fixes.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
CHANGELOG.md Records the four fixes.
nvim/lua/gerrrt/config/providers.lua Updates provider configuration and rationale.
nvim/lua/gerrrt/plugins/gitsigns-nvim.lua Passes visual selections to hunk actions.
nvim/lua/gerrrt/plugins/lualine-nvim.lua Allows the NvimTree extension to render.
nvim/lua/gerrrt/plugins/mini-nvim.lua Explicitly defines gsn.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread nvim/lua/gerrrt/config/providers.lua Outdated
Comment on lines 23 to 26
-- Python3 provider: LEFT ENABLED, and unlike node this is load-bearing. vimade probes
-- `has('python3')` (vimade/autoload/vimade.vim:80) and selects a python renderer when present, so
-- disabling it silently downgrades a plugin actually in use. Do not "tidy" this one away.
-- vim.g.loaded_python3_provider = 0
Comment thread CHANGELOG.md Outdated
Comment on lines +148 to +150
0 warnings** across every section. The python3 provider is explicitly left enabled and documented
as load-bearing: `vimade` probes `has('python3')` (`vimade/autoload/vimade.vim:80`) and picks a
python renderer when present.
…nale

Addresses both review comments on #257. The reviewer was right and my claim was
wrong.

I asserted the python3 provider was load-bearing because vimade probes
has('python3'). That grep-deep reading missed the control flow:
vimade#SetupRenderer() (autoload/vimade.vim:30-43) short-circuits to the Lua
renderer whenever renderer == 'auto' and supports_lua_renderer, and only the
ELSE branch calls SetupPython(). supports_lua_renderer is
(nvim_get_hl or nvim__get_hl_defs) and nvim_win_set_hl_ns (:112) — all present
since 0.11, and nvim-treesitter's main branch already hard-requires 0.12 here,
so the python fallback is unreachable on any Neovim this config supports.

Confirmed at runtime rather than by reading: renderer=auto,
supports_lua_renderer=1, ACTIVE renderer=lua, vimade_python_setup=0, and the
has_python3 field was never even populated — SetupPythonFeatures() never ran, so
has('python3') was never evaluated.

vimade is also the only reference to python anywhere in the tree; nothing else
uses py3eval/pynvim, and nvim-dap-python spawns debugpy as an external DAP
adapter subprocess, which does not involve this provider.

So python3 is disabled alongside node. That is what makes the cleanup portable:
left enabled, any fleet machine without pynvim keeps emitting the same
:checkhealth warning this change set out to remove. Verified vimade still
selects the Lua renderer with the provider off, and :checkhealth remains
0 errors / 0 warnings.

The CHANGELOG rationale is rewritten; it no longer calls python load-bearing or
claims the python renderer is chosen merely when python3 is present.

Validated: luacheck 0/0 across 86 files, checkhealth 0 errors / 0 warnings,
make audit 222 pass / 0 fail.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018wpwbjkGJKPFgvBFEKsFWE
@Gerrrt

Gerrrt commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator Author

Both comments addressed in 86da65c. You were right on both counts — my claim was wrong, and the reason is exactly the control flow you pointed at.

I had grepped for has('python3'), found it at autoload/vimade.vim:80, and concluded the provider was load-bearing. That skipped the dispatch. vimade#SetupRenderer() (autoload/vimade.vim:30-43) short-circuits to the Lua renderer whenever renderer == 'auto' and supports_lua_rendererSetupPython() is only reached in the else branch. And supports_lua_renderer is (nvim_get_hl or nvim__get_hl_defs) and nvim_win_set_hl_ns (:112), all present since 0.11 — with nvim-treesitter's main branch already hard-requiring 0.12 here, the python path is unreachable on any Neovim this config supports.

Confirmed at runtime rather than by reading:

configured renderer   = auto
supports_lua_renderer = 1
ACTIVE renderer       = lua
vimade_python_setup   = 0
has_python3 field     = nil      <- SetupPythonFeatures() never ran;
                                    has('python3') was never evaluated

That last line is the clincher: the function containing the probe I based my claim on never executes.

I also checked vimade is the only python reference in the tree — nothing else uses py3eval/pynvim, and nvim-dap-python spawns debugpy as an external DAP adapter subprocess, which doesn't involve this provider.

So python3 is now disabled alongside node, which is your portability point: left enabled, any fleet machine without pynvim keeps emitting the same warning this change set out to remove. Verified vimade still selects the Lua renderer with the provider off:

ACTIVE renderer = lua   supports_lua_renderer = 1   python_setup = 0

The CHANGELOG rationale is rewritten — it no longer calls python load-bearing, and no longer claims the python renderer is selected merely when python3 is present. It now documents the short-circuit and the runtime evidence.

Re-validated: luacheck 0/0 across 86 files, :checkhealth 0 errors / 0 warnings across every section, make audit 222 pass / 0 fail.

@Gerrrt
Gerrrt merged commit 6c503aa into main Jul 20, 2026
14 checks passed
@Gerrrt
Gerrrt deleted the nvim-statusline-gitsigns-provider-fixes branch July 20, 2026 13:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants