Small Neovim plugin that uses the codex CLI to fill in a selected code range.
Select a stub, empty function, or partial implementation, run Codex Fill, and the plugin replaces only the selected lines with Codex's final answer.
ThePrimeagen's _99 has been haunting me for half a year now. I knew that this concept was really good, but I did not want to use his version mainly because of skill issues (I have a disgust for lua unfortunately, I don't like it and I don't want to learn it). By coincidence, I have a quite big codex subscription (AFAIK his project does not support the codex yet) and as a result of this, the project has been shamelessly vibecoded.
- Neovim 0.10+ with Lua support
codexavailable on yourPATH- Codex CLI already logged in and working from a terminal
Check Codex:
codex --version
codex exec "Say OK"For local development, point lazy.nvim at this directory:
{
dir = "/home/domanskiba/codex-fill",
name = "codex-fill.nvim",
config = function()
require("codex_fill").setup()
end,
}If you use Kickstart.nvim, put that spec in
~/.config/nvim/lua/custom/plugins/codex-fill.lua:
return {
{
dir = "/home/domanskiba/codex-fill",
name = "codex-fill.nvim",
config = function()
require("codex_fill").setup {
keymap = "<leader>cf",
model = nil,
}
end,
},
}Make sure Kickstart imports custom plugins in init.lua:
{ import = "custom.plugins" },You can also load it without a plugin manager:
vim.opt.runtimepath:prepend("/home/domanskiba/codex-fill")
require("codex_fill").setup()- Open a code file.
- Select the code to replace with visual mode.
- Press
<leader>cf. - Enter an instruction, or press Enter with an empty prompt for the default fill behavior.
Example:
fn main() {
say_hello_world();
}
fn say_hello_world() {
}Select the whole say_hello_world function, press <leader>cf, and leave the
instruction empty. Codex Fill asks Codex to infer the missing body from the
function name and surrounding buffer.
You can also provide a visual range command:
:'<,'>CodexFill print hello worldDefault setup:
require("codex_fill").setup {
codex_cmd = "codex",
keymap = "<leader>cf",
model = nil,
notify = true,
}Options:
codex_cmd: executable name or path for the Codex CLI.keymap: visual mode mapping. Set tofalseor""to skip keymap creation.model: optional Codex model. Whennil, Codex uses your normal CLI config.notify: show Neovim notifications for start/success/failure.
- Runs
codex execasynchronously. - Uses the nearest git root as Codex working directory.
- Runs Codex with
--sandbox read-only. - Sends Codex the selected range, current file path, filetype, and full current buffer.
- Applies only Codex's final response to the selected line range.
- Strips a single surrounding markdown code fence when Codex returns one.
- Leaves the buffer unchanged if Codex fails, returns empty output, returns identical text, or if the buffer changed while Codex was running.
- True rectangular Visual Block selections are rejected for now. Use visual line or visual character selection instead.
- The plugin replaces whole touched lines, not arbitrary character spans.
- It does not autoformat after replacement.
- It does not preview diffs before applying.
Run the headless smoke test:
nvim --headless -u NONE -S test/headless.luaLoad through your Neovim config:
nvim --headless -u ~/.config/nvim/init.lua '+lua require("codex_fill")' +qa