@@ -15,6 +15,8 @@ local config = {
1515 cmd = ' codex' ,
1616 model = nil , -- Default to the latest model
1717 autoinstall = true ,
18+ panel = false , -- if true, open Codex in a side-panel instead of floating window
19+ use_buffer = false , -- if true, capture Codex stdout into a normal buffer instead of a terminal
1820}
1921
2022function M .setup (user_config )
@@ -86,6 +88,18 @@ local function open_window()
8688 })
8789end
8890
91+ --- Open Codex in a side-panel (vertical split) instead of floating window
92+ local function open_panel ()
93+ -- Create a vertical split on the right and show the buffer
94+ vim .cmd (' vertical rightbelow vsplit' )
95+ local win = vim .api .nvim_get_current_win ()
96+ vim .api .nvim_win_set_buf (win , state .buf )
97+ -- Adjust width according to config (percentage of total columns)
98+ local width = math.floor (vim .o .columns * config .width )
99+ vim .api .nvim_win_set_width (win , width )
100+ state .win = win
101+ end
102+
89103function M .open ()
90104 local function create_clean_buf ()
91105 local buf = vim .api .nvim_create_buf (false , false )
@@ -128,7 +142,7 @@ function M.open()
128142 ' You can install manually with:' ,
129143 ' npm install -g @openai/codex' ,
130144 })
131- open_window ()
145+ if config . panel then open_panel () else open_window () end
132146 end
133147 end )
134148 return
@@ -145,7 +159,7 @@ function M.open()
145159 ' ' ,
146160 ' Or enable autoinstall in setup: require("codex").setup{ autoinstall = true }' ,
147161 })
148- open_window ()
162+ if config . panel then open_panel () else open_window () end
149163 return
150164 end
151165 end
@@ -158,21 +172,53 @@ function M.open()
158172 state .buf = create_clean_buf ()
159173 end
160174
161- open_window ()
175+ if config . panel then open_panel () else open_window () end
162176
163177 if not state .job then
178+ -- assemble command
164179 local cmd_args = type (config .cmd ) == ' string' and { config .cmd } or vim .deepcopy (config .cmd )
165180 if config .model then
166181 table.insert (cmd_args , ' -m' )
167182 table.insert (cmd_args , config .model )
168183 end
169184
170- state .job = vim .fn .termopen (cmd_args , {
171- cwd = vim .loop .cwd (),
172- on_exit = function ()
173- state .job = nil
174- end ,
175- })
185+ if config .use_buffer then
186+ -- capture stdout/stderr into normal buffer
187+ state .job = vim .fn .jobstart (cmd_args , {
188+ cwd = vim .loop .cwd (),
189+ stdout_buffered = true ,
190+ on_stdout = function (_ , data )
191+ if not data then return end
192+ for _ , line in ipairs (data ) do
193+ if line ~= ' ' then
194+ vim .api .nvim_buf_set_lines (state .buf , - 1 , - 1 , false , { line })
195+ end
196+ end
197+ end ,
198+ on_stderr = function (_ , data )
199+ if not data then return end
200+ for _ , line in ipairs (data ) do
201+ if line ~= ' ' then
202+ vim .api .nvim_buf_set_lines (state .buf , - 1 , - 1 , false , { ' [ERR] ' .. line })
203+ end
204+ end
205+ end ,
206+ on_exit = function (_ , code )
207+ state .job = nil
208+ vim .api .nvim_buf_set_lines (state .buf , - 1 , - 1 , false , {
209+ (' [Codex exit: %d]' ):format (code ),
210+ })
211+ end ,
212+ })
213+ else
214+ -- use a terminal buffer
215+ state .job = vim .fn .termopen (cmd_args , {
216+ cwd = vim .loop .cwd (),
217+ on_exit = function ()
218+ state .job = nil
219+ end ,
220+ })
221+ end
176222 end
177223end
178224
0 commit comments