Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
> Latest version: ![GitHub tag (latest SemVer)](https://img.shields.io/github/v/tag/johnseth97/codex.nvim?sort=semver)

### Features:
- ✅ Toggle Codex floating window with `:CodexToggle`
- ✅ Toggle Codex window or side-panel with `:CodexToggle`
- ✅ Optional keymap mapping via `setup` call
- ✅ Background running when window hidden
- ✅ Statusline integration via `require('codex').status()`
Expand All @@ -29,14 +29,14 @@ export OPENAI_API_KEY=your_api_key

```lua
return {
'johnseth97/codex.nvim',
'kkrampis/codex.nvim',
lazy = true,
cmd = { 'Codex', 'CodexToggle' }, -- Optional: Load only on command execution
keys = {
{
'<leader>cc', -- Change this to your preferred keybinding
function() require('codex').toggle() end,
desc = 'Toggle Codex popup',
desc = 'Toggle Codex popup or side-panel',
mode = { 'n', 't' }
},
},
Expand All @@ -50,12 +50,16 @@ return {
height = 0.8, -- Height of the floating window (0.0 to 1.0)
model = nil, -- Optional: pass a string to use a specific model (e.g., 'o3-mini')
autoinstall = true, -- Automatically install the Codex CLI if not found
panel = false, -- Open Codex in a side-panel (vertical split) instead of floating window
use_buffer = false, -- Capture Codex stdout into a normal buffer instead of a terminal buffer
},
}```
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

The code block syntax is malformed. Line 54 shows `}````, which combines the closing brace with the three backticks. These should be on separate lines for proper markdown formatting:

  },
}

(closing backticks on next line)

Suggested change
}```
}

Copilot uses AI. Check for mistakes.

### Usage:
- Call `:Codex` (or `:CodexToggle`) to open or close the Codex popup.
-- Map your own keybindings via the `keymaps.toggle` setting.
- Call `:Codex` (or `:CodexToggle`) to open or close the Codex popup or side-panel.
- Map your own keybindings via the `keymaps.toggle` setting.
- To choose floating popup vs side-panel, set `panel = false` (popup) or `panel = true` (panel) in your setup options.
- To capture Codex output in an editable buffer instead of a terminal, set `use_buffer = true` (or `false` to keep terminal) in your setup options.
- Add the following code to show backgrounded Codex window in lualine:

```lua
Expand All @@ -66,4 +70,3 @@ require('codex').status() -- drop in to your lualine sections
- All plugin configurations can be seen in the `opts` table of the plugin setup, as shown in the installation section.

- **For deeper customization, please refer to the [Codex CLI documentation](https://github.com/openai/codex?tab=readme-ov-file#full-configuration-example) full configuration example. These features change quickly as Codex CLI is in active beta development.*

64 changes: 55 additions & 9 deletions lua/codex/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ local config = {
cmd = 'codex',
model = nil, -- Default to the latest model
autoinstall = true,
panel = false, -- if true, open Codex in a side-panel instead of floating window
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

[nitpick] The inline comments for the new config options use inconsistent spacing. Line 15 has panel = false, with extra spaces, while line 16 has use_buffer = false, with normal spacing. Align the equals signs consistently for better readability.

Suggested change
panel = false, -- if true, open Codex in a side-panel instead of floating window
panel = false, -- if true, open Codex in a side-panel instead of floating window

Copilot uses AI. Check for mistakes.
use_buffer = false, -- if true, capture Codex stdout into a normal buffer instead of a terminal
}

function M.setup(user_config)
Expand Down Expand Up @@ -86,6 +88,18 @@ local function open_window()
})
end

--- Open Codex in a side-panel (vertical split) instead of floating window
local function open_panel()
-- Create a vertical split on the right and show the buffer
vim.cmd('vertical rightbelow vsplit')
local win = vim.api.nvim_get_current_win()
vim.api.nvim_win_set_buf(win, state.buf)
Comment on lines +95 to +96
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

[nitpick] The open_panel() function uses vim.cmd('vertical rightbelow vsplit') which creates a new empty buffer before switching to state.buf. This temporarily creates an unnecessary buffer. Consider using vim.api.nvim_open_win(state.buf, true, {...}) with appropriate split configuration, or explicitly delete the temporary buffer after the split.

Suggested change
local win = vim.api.nvim_get_current_win()
vim.api.nvim_win_set_buf(win, state.buf)
local win = vim.api.nvim_get_current_win()
local tmp_buf = vim.api.nvim_win_get_buf(win)
vim.api.nvim_win_set_buf(win, state.buf)
-- Delete the temporary buffer if it's not the same as state.buf and is listed
if tmp_buf ~= state.buf and vim.api.nvim_buf_is_valid(tmp_buf) then
-- Only delete if the buffer is listed (to avoid deleting user buffers)
if vim.api.nvim_buf_get_option(tmp_buf, 'buflisted') then
vim.api.nvim_buf_delete(tmp_buf, { force = true })
end
end

Copilot uses AI. Check for mistakes.
-- Adjust width according to config (percentage of total columns)
local width = math.floor(vim.o.columns * config.width)
vim.api.nvim_win_set_width(win, width)
state.win = win
end

function M.open()
local function create_clean_buf()
local buf = vim.api.nvim_create_buf(false, false)
Expand Down Expand Up @@ -128,7 +142,7 @@ function M.open()
'You can install manually with:',
' npm install -g @openai/codex',
})
open_window()
if config.panel then open_panel() else open_window() end
end
end)
return
Expand All @@ -145,7 +159,7 @@ function M.open()
'',
'Or enable autoinstall in setup: require("codex").setup{ autoinstall = true }',
})
open_window()
if config.panel then open_panel() else open_window() end
return
end
end
Expand All @@ -158,21 +172,53 @@ function M.open()
state.buf = create_clean_buf()
end

open_window()
if config.panel then open_panel() else open_window() end

if not state.job then
-- assemble command
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

[nitpick] The inline comment -- assemble command should be capitalized and end with a period for consistency with documentation standards: -- Assemble command.

Suggested change
-- assemble command
-- Assemble command.

Copilot uses AI. Check for mistakes.
local cmd_args = type(config.cmd) == 'string' and { config.cmd } or vim.deepcopy(config.cmd)
if config.model then
table.insert(cmd_args, '-m')
table.insert(cmd_args, config.model)
end

state.job = vim.fn.termopen(cmd_args, {
cwd = vim.loop.cwd(),
on_exit = function()
state.job = nil
end,
})
if config.use_buffer then
-- capture stdout/stderr into normal buffer
state.job = vim.fn.jobstart(cmd_args, {
cwd = vim.loop.cwd(),
stdout_buffered = true,
on_stdout = function(_, data)
if not data then return end
for _, line in ipairs(data) do
if line ~= '' then
vim.api.nvim_buf_set_lines(state.buf, -1, -1, false, { line })
end
end
end,
on_stderr = function(_, data)
if not data then return end
for _, line in ipairs(data) do
if line ~= '' then
vim.api.nvim_buf_set_lines(state.buf, -1, -1, false, { '[ERR] ' .. line })
end
end
end,
on_exit = function(_, code)
state.job = nil
vim.api.nvim_buf_set_lines(state.buf, -1, -1, false, {
('[Codex exit: %d]'):format(code),
})
end,
Comment on lines +190 to +211
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

The on_stdout, on_stderr, and on_exit callbacks don't verify that state.buf is still valid before writing to it. If the user closes the buffer while the job is still running, nvim_buf_set_lines will throw an error. Add a buffer validity check:

if not vim.api.nvim_buf_is_valid(state.buf) then return end

at the start of each callback.

Copilot uses AI. Check for mistakes.
})
Comment on lines +185 to +212
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

When using use_buffer = true, the buffer is not a terminal buffer, so users cannot interact with the Codex CLI (send input). The jobstart call doesn't configure stdin handling. If the Codex CLI requires user input, consider either:

  1. Adding stdin = 'pipe' and implementing an input mechanism
  2. Documenting that use_buffer = true is read-only and doesn't support interactive sessions
  3. Using pty = true to enable terminal-like behavior while still capturing output

Currently, this creates a non-interactive experience that may not work correctly with Codex CLI.

Copilot uses AI. Check for mistakes.
else
-- use a terminal buffer
Comment on lines +186 to +214
Copy link

Copilot AI Nov 20, 2025

Choose a reason for hiding this comment

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

[nitpick] Inconsistent inline comment style. Line 175 uses -- capture stdout/stderr into normal buffer (lowercase, no period) while line 203 uses -- use a terminal buffer (lowercase, no period). For consistency with the function-level comment on line 88 which uses proper capitalization and punctuation, consider standardizing all comments to use sentence case with proper punctuation.

Copilot uses AI. Check for mistakes.
state.job = vim.fn.termopen(cmd_args, {
cwd = vim.loop.cwd(),
on_exit = function()
state.job = nil
end,
})
end
end
end

Expand Down