Installation
July 30, 2026 · View on GitHub
The README covers the two canonical setups. This page collects the variants: full vim.pack parity, coexisting with a completion plugin, and pinning a version.
Contents
- What the lazy.nvim spec actually does
- vim.pack: full parity with the lazy.nvim spec
- Letting nvim-cmp / blink.cmp own
<Tab> - Pinning a version
What the lazy.nvim spec actually does
{
"teocns/neocursor.nvim",
event = "InsertEnter",
build = 'uv run --with "httpx[http2]" python -c "import httpx"',
opts = {},
}
Three things worth knowing, because the vim.pack equivalent has to reproduce them by hand:
event = "InsertEnter"defers startup until you first enter insert mode. Nothing is spawned while you're just reading files.buildpre-warms the sidecar's Python dependencies at install time, so the first suggestion isn't waiting on a download. The double quotes matter — they let bothcmd.exeandshparse the argument.opts = {}callssetup()with defaults. There is nothing you're required to configure.
vim.pack: full parity with the lazy.nvim spec
The minimal form is in the README. This reproduces the pre-warm and the lazy start:
-- pre-warm the sidecar's deps on install/update (lazy.nvim's `build`).
-- Register this BEFORE vim.pack.add so it sees the initial install.
vim.api.nvim_create_autocmd("PackChanged", {
callback = function(ev)
if ev.data.spec.name ~= "neocursor.nvim" then return end
if ev.data.kind == "install" or ev.data.kind == "update" then
vim.system { "uv", "run", "--with", "httpx[http2]", "python", "-c", "import httpx" }
end
end,
})
vim.pack.add { "https://github.com/teocns/neocursor.nvim" }
-- start on first insert (lazy.nvim's `event = "InsertEnter"`)
vim.api.nvim_create_autocmd("InsertEnter", {
once = true,
callback = function() require("neocursor").setup {} end,
})
Skipping the pre-warm is fine — the sidecar fetches its own deps on first launch; the first suggestion just arrives a few seconds later.
vim.packis built into Neovim ≥ 0.12. On 0.10–0.11, use a plugin manager.
Letting nvim-cmp / blink.cmp own <Tab>
By default neocursor maps <Tab> in insert mode. If another plugin already
owns it, set map_tab = false and call into neocursor from your own handler:
{ "teocns/neocursor.nvim", event = "InsertEnter", opts = { map_tab = false } }
-- in your <Tab> mapping, try neocursor first:
if require("neocursor").accept() then return end
-- …otherwise let cmp / blink / your snippet engine handle it
accept() returns true if it consumed the key — there was a suggestion to
accept, an edit to jump to, or a chain to advance — and false if there was
nothing pending. That makes it safe as the first branch: when neocursor has
nothing to offer, your existing behavior is untouched.
Not sure who currently owns the key? :verbose imap <Tab> names the file that
mapped it last.
Pinning a version
Track tagged releases instead of main:
{ "teocns/neocursor.nvim", version = "*" }
With vim.pack, version takes a tag, branch, commit hash, or a
vim.version.range():
vim.pack.add {
{ src = "https://github.com/teocns/neocursor.nvim", version = vim.version.range "*" },
}
This is a beta and main moves; pinning is reasonable if you'd rather adopt
changes deliberately. See releases.