Skip to content

yaadata/codex.nvim

Repository files navigation

codex.nvim

Neovim plugin for running the Codex CLI in an embedded terminal.

Requirements

  • Neovim >= 0.11.0
  • codex available on your PATH (or configure launch.cmd)

Caution

You are reading the main branch README. Install and configuration details may differ from tagged releases. The current latest release tag is v0.5.0. For version-accurate instructions, read the README for your target tag from Codeberg releases.

Install

{
  url = "https://codeberg.org/yaadata/codex.nvim.git",
  version = "0.5.0",
  cmd = {
    "Codex",
    "CodexFocus",
    "CodexClose",
    "CodexClearInput",
    "CodexSend",
    "CodexAddBuffer",
    "CodexMentionFile",
    "CodexMentionDirectory",
    "CodexResume",
    "CodexModel",
    "CodexStatus",
    "CodexPermissions",
    "CodexCompact",
    "CodexReview",
    "CodexDiff",
  },
  opts = {},
  config = function(_, opts)
    require("codex").setup(opts)
  end,
}

Configuration

Use this table as your lazy.nvim plugin opts value:

Show default opts table
opts = {
  launch = {
    cmd = "codex",
    args = {},
    env = {},
    auto_start = true,
    cwd = nil,
  },
  log = {
    level = "warn",
    verbose = false,
  },
  terminal = {
    provider = "auto", -- auto | snacks | native
    provider_opts = {
      native = {
        window = "vsplit", -- vsplit | hsplit | float
        vsplit = {
          side = "right", -- left | right
          size_pct = 40, -- 10-90
        },
        hsplit = {
          side = "bottom", -- top | bottom
          size_pct = 30, -- 10-90
        },
        float = {
          width_pct = 80, -- 10-100
          height_pct = 80, -- 10-100
          border = "rounded",
          title = " Codex ",
          title_pos = "center", -- left | center | right
        },
      },
      snacks = {
        -- pass-through for snacks.terminal(..., opts)
      },
    },
    auto_close = true, -- close terminal buffer automatically when process exits
    startup = {
      timeout_ms = 2000, -- max time to wait for startup readiness before dropping queued sends
      retry_interval_ms = 50, -- retry interval while waiting for startup readiness
      grace_ms = 800, -- minimum delay after terminal open before first send
    },
    keymaps = {}, -- terminal-local keymaps are opt-in; no defaults are registered
  },
}

Commands

  • :Codex toggles the Codex terminal
  • :Codex! force-opens and focuses the Codex terminal
  • :CodexFocus focuses the terminal (opens it if needed)
  • :CodexClose closes the active Codex terminal session
  • :CodexClearInput clears the active Codex terminal input line
  • :CodexSend sends selected lines with path and range context.
  • :CodexAddBuffer sends current buffer path as ACP file reference (@path).
  • :CodexMentionFile [path] sends /mention for a file path, normalized to cwd-relative.
  • :CodexMentionDirectory [path] sends /mention for a directory path, normalized to cwd-relative and forced to end with a path separator.
  • :CodexResume[!] resumes in-process or launches codex resume (! uses --last when launching).
  • :CodexModel sends /model
  • :CodexStatus sends /status
  • :CodexPermissions sends /permissions
  • :CodexCompact sends /compact
  • :CodexReview [instructions] sends /review.
  • :CodexDiff sends /diff

For detailed command behavior and component interactions, see docs/command-interactions.md.

When using lazy.nvim with cmd + opts, prefer wiring setup explicitly in config and passing lazy's resolved opts through:

config = function(_, opts)
  require("codex").setup(opts)
end

The cmd list still ensures first-use lazy loading when a :Codex* command is run.

Keymaps

codex.nvim does not register global keymaps in setup(). Define global mappings in your lazy.nvim plugin spec keys:

Show lazy keys table
{
  url = "https://codeberg.org/yaadata/codex.nvim.git",
  version = "0.5.0",
  main = "codex",
  cmd = {
    "Codex",
    "CodexFocus",
    "CodexClose",
    "CodexClearInput",
    "CodexSend",
    "CodexAddBuffer",
    "CodexMentionFile",
    "CodexMentionDirectory",
    "CodexResume",
    "CodexModel",
    "CodexStatus",
    "CodexPermissions",
    "CodexCompact",
    "CodexReview",
    "CodexDiff",
  },
  opts = {},
  config = function(_, opts)
    require("codex").setup(opts)
  end,
  keys = {
    {
      "<leader>ot",
      function()
        require("codex").toggle()
      end,
      desc = "Codex: Toggle terminal",
      mode = { "n", "v" },
    },
    {
      "<leader>os",
      function()
        require("codex").send_buffer()
      end,
      desc = "Codex: Add current buffer",
      mode = "n",
    },
    {
      "<leader>os",
      function()
        require("codex").send_selection()
      end,
      desc = "Codex: Send selection",
      mode = "x",
    },
    {
      "<leader>om",
      function()
        require("codex").mention_file()
      end,
      desc = "Codex: Mention current file",
      mode = { "n", "v" },
    },
    {
      "<leader>oM",
      function()
        require("codex").mention_directory()
      end,
      desc = "Codex: Mention current directory",
      mode = { "n", "v" },
    },
    {
      "<leader>or",
      function()
        require("codex").resume()
      end,
      desc = "Codex: Resume session",
      mode = { "n", "v" },
    },
    {
      "<leader>oi",
      function()
        require("codex").show_status()
      end,
      desc = "Codex: Show status",
      mode = { "n", "v" },
    },
    {
      "<leader>op",
      function()
        require("codex").show_permissions()
      end,
      desc = "Codex: Permissions",
      mode = { "n", "v" },
    },
    {
      "<leader>oc",
      function()
        require("codex").compact()
      end,
      desc = "Codex: Compact context",
      mode = { "n", "v" },
    },
    {
      "<leader>oR",
      function()
        require("codex").review()
      end,
      desc = "Codex: Review changes",
      mode = { "n", "v" },
    },
    {
      "<leader>od",
      function()
        require("codex").show_diff()
      end,
      desc = "Codex: Show diff",
      mode = { "n", "v" },
    },
  },
}

Set vim.g.mapleader before plugin setup so <leader> expands as expected.

Terminal-local keymaps inside the Codex terminal buffer are configured separately via terminal.keymaps:

local km = require("codex.keymaps").builtins

require("codex").setup({
  log = {
    level = "warn",
    verbose = false,
  },
  terminal = {
    keymaps = {
      ["<C-c>"] = { mode = { "t", "n" }, action = km.toggle },
      ["<M-BS>"] = { mode = { "t", "n" }, action = km.clear_input },
      ["<C-x>"] = { mode = { "t", "n" }, action = km.close },
      ["<A-h>"] = { mode = { "t", "n" }, action = km.nav_left },
      ["<A-j>"] = { mode = { "t", "n" }, action = km.nav_down },
      ["<A-k>"] = { mode = { "t", "n" }, action = km.nav_up },
      ["<A-l>"] = { mode = { "t", "n" }, action = km.nav_right },
    },
  },
})

Each entry uses { mode, action, desc? }, where:

  • mode is a string or list of modes accepted by vim.keymap.set.
  • action is a function (for builtins, use require("codex.keymaps").builtins).
  • desc is optional for builtin actions (auto-filled), required for custom actions.

terminal.auto_close controls whether provider windows auto-close only after the terminal process exits.

Lua API

The authoritative Lua API reference lives in docs/api.md.

For :Codex* command behavior and component interaction details, see docs/command-interactions.md.

Providers

auto (default) prefers snacks when available, falls back to native. See docs/architecture.md for the full provider interface and implementation details.

Development

See docs/contributing.md for setup, testing, formatting, linting, and code style guidelines.

Troubleshooting

See docs/troubleshooting.md for logging-focused debugging steps and issue report guidance.

About

Read only mirror of https://codeberg.org/yaadata/codex.nvim

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages