Skip to content

[audit] Fix vim-sneak module guard — use autoload check instead of require - #113

Merged
stanfish06 merged 2 commits into
masterfrom
audit/fix-vim-sneak-module-guard
May 28, 2026
Merged

stanfish06 merged 2 commits into
masterfrom
audit/fix-vim-sneak-module-guard

Conversation

@stanfish06

Copy link
Copy Markdown
Owner

What

lua/config/plugin_config.lua (line 43, before this PR) guarded all vim-sneak configuration behind:

local sneaks_ok, _ = pcall(require, "sneak")

vim-sneak is a Vimscript plugin — it has no Lua module named sneak. pcall(require, "sneak") therefore always returns false, silently making the entire block dead code:

  • vim.g["sneak#label"] = 1 (label/EasyMotion-style jump targets) — never set
  • vim.g["sneak#use_ic_scs"] = 1 (smartcase) — never set
  • f, F, t, T remapped to <Plug>Sneak_f/F/t/T — never applied

The plugin itself loads fine (it lives in pack/plugins/start/sneaks.vim/), but all its configuration was silently dropped every time Neovim started.

Where

lua/config/plugin_config.lua, previously line 43.

Why it matters

Without label mode the plugin is functionally equivalent to plain f/t — the distinguishing EasyMotion-style jump-target overlay never appears. The smartcase option also stays off.

Fix

Replace the Lua-module require guard with a check against vim-sneak's actual autoload entry point:

local sneaks_ok = vim.fn.exists("*sneak#wrap") == 1

sneak#wrap is the function vim-sneak's Vimscript defines on load. It is present if and only if the plugin was sourced, making it the correct runtime probe for a Vimscript plugin.

Testing

  1. Install sneaks.vim as usual (SyncPkgs).
  2. Open any file, press f — jump-target labels should appear (EasyMotion-style).
  3. With sneak#use_ic_scs, typing an uppercase char should match only that case.
  4. Without the plugin installed, sneaks_ok is false and nothing is set (same behavior as before).

Generated by Claude Code

…dule)

pcall(require, "sneak") always returns false because vim-sneak is a
Vimscript plugin with no Lua module named "sneak". This silently
disabled all sneak configuration: label mode, smartcase, and the
f/F/t/T keymaps were never applied.

Replace the require guard with vim.fn.exists("*sneak#wrap"), which
checks for the plugin's actual autoload entry point.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e8b19b97cb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread lua/config/plugin_config.lua Outdated
local sneaks_ok, _ = pcall(require, "sneak")
-- vim-sneak is a Vimscript plugin: it has no Lua module, so require("sneak") always fails.
-- Check for its autoload entry point instead.
local sneaks_ok = vim.fn.exists("*sneak#wrap") == 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Use a plugin-load marker instead of an autoload function

When vim-sneak is installed, this guard still evaluates false because sneak#wrap lives in autoload/sneak.vim; Vim/Neovim autoload functions are not defined until the function is first called or the autoload file is explicitly sourced. The plugin’s startup script only installs mappings whose RHS calls sneak#wrap, so at plugin_config.lua startup this check leaves the entire configuration block dead and the intended f/F/t/T mappings are still skipped. Check a startup marker such as g:loaded_sneak_plugin (or the installed <Plug> mapping) instead.

Useful? React with 👍 / 👎.

@stanfish06

Copy link
Copy Markdown
Owner Author

there is lua/sneak.lua that is loadable, and current check returns true

@stanfish06 stanfish06 closed this May 28, 2026
@stanfish06 stanfish06 reopened this May 28, 2026
@stanfish06

Copy link
Copy Markdown
Owner Author

so sneak.lua appears to handle highlight, i suppose that is sufficient for simple check but you can update pr if better approach exists. this is what sneak.lua does:

function M.init()
  vim.api.nvim_set_decoration_provider(ns, {
    on_start = function(_, _)
      if not matches then
        return false
      end
    end,
    on_win = function(_, win, _, _, _)
      if win ~= vim.api.nvim_get_current_win() then
        return false
      end
      for _, m in ipairs(matches) do
        local c, row, col = unpack(m)
        vim.api.nvim_buf_set_extmark(0, ns, row, col, {
          priority = 1000,
          virt_text = { {c, 'SneakLabel'} },
          virt_text_pos = 'overlay',
          ephemeral = true,
        })
      end
    end
  })
end

@claude

@claude

claude Bot commented May 28, 2026 •

Copy link
Copy Markdown

Claude finished @stanfish06's task in 1m 47s —— View job


Updated guard to vim.g.loaded_sneak_plugin

  • Read current file state and understand the sneak.lua context
  • Determine best guard: vim.g.loaded_sneak_plugin ~= nil
  • Update the PR with the correct approach

What changed (lua/config/plugin_config.lua:45):

-- before (PR)
local sneaks_ok = vim.fn.exists("*sneak#wrap") == 1

-- after
local sneaks_ok = vim.g.loaded_sneak_plugin ~= nil

Why each approach fails:

  • pcall(require, "sneak") — was matching lua/sneak.lua (the highlight companion), not vim-sneak itself; the guard happened to work but for the wrong reason
  • vim.fn.exists("*sneak#wrap") — Codex was right: sneak#wrap is in autoload/sneak.vim and Neovim only defines autoload functions on first call, so this is always 0 at startup
  • vim.g.loaded_sneak_plugin — correct standard Vim idiom: plugin/sneak.vim sets this variable unconditionally when it sources at startup (before any autoload lazy-loading)
    |

sneak#wrap lives in autoload/sneak.vim and is not defined at startup,
making vim.fn.exists("*sneak#wrap") always return 0. The standard Vim
idiom is to check the g:loaded_* variable that plugin/sneak.vim sets
when it sources.

Co-authored-by: Zhiyuan <stanfish06@users.noreply.github.com>
@stanfish06
stanfish06 merged commit 29a1c7a into master May 28, 2026
1 check failed
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.

1 participant