From a007f382cee0ae4ca8bb17ade422a625df25baef Mon Sep 17 00:00:00 2001 From: Konstantinos Krampis Date: Wed, 13 Aug 2025 12:18:04 -0400 Subject: [PATCH] mod for side panel mode and buffer copy --- README.md | 17 +++++++----- lua/codex/init.lua | 64 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 65 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 62a4d95..9baacc6 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,12 @@ image ## A Neovim plugin integrating the open-sourced Codex CLI (`codex`). -> Latest version: ![GitHub tag (latest SemVer)](https://img.shields.io/github/v/tag/johnseth97/codex.nvim?sort=semver) +> Latest version: ![GitHub tag (latest SemVer)](https://img.shields.io/github/v/tag/kkrampis/codex.nvim?sort=semver) Note: As of v1.0.0, no longer closes the Codex window. Press q to close, and to safely interrupt model generation without resetting context. ### 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()` @@ -31,14 +31,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 = { { 'cc', -- Change this to your preferred keybinding function() require('codex').toggle() end, - desc = 'Toggle Codex popup', + desc = 'Toggle Codex popup or side-panel', }, }, opts = { @@ -48,12 +48,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 }, }``` ### 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 @@ -64,4 +68,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.* - diff --git a/lua/codex/init.lua b/lua/codex/init.lua index 22a4f26..0bf576f 100644 --- a/lua/codex/init.lua +++ b/lua/codex/init.lua @@ -12,6 +12,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 + use_buffer = false, -- if true, capture Codex stdout into a normal buffer instead of a terminal } function M.setup(user_config) @@ -83,6 +85,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) + -- 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) @@ -117,7 +131,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 @@ -134,7 +148,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 @@ -147,21 +161,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 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, + }) + else + -- use a terminal buffer + state.job = vim.fn.termopen(cmd_args, { + cwd = vim.loop.cwd(), + on_exit = function() + state.job = nil + end, + }) + end end end