Skip to content

Commit d257148

Browse files
yaadatayaadata
authored andcommitted
feat(codex): add clear_input command and terminal keymap (#5)
- add `clear_input()` API and `:CodexClearInput` command - add `terminal.keymaps.clear_input` (default `<M-BS>`) in config/types/validation - wire terminal-local clear-input mappings in native and snacks providers - add/update unit tests and docs Reviewed-on: https://codeberg.org/yaadata/codex.nvim/pulls/5 Co-authored-by: Yadi Abdalhalim <abdalhalim.yaadata@gmail.com> Co-committed-by: Yadi Abdalhalim <abdalhalim.yaadata@gmail.com>
1 parent 91c1a2c commit d257148

13 files changed

Lines changed: 312 additions & 62 deletions

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ require("codex").setup({
5656
},
5757
keymaps = {
5858
toggle = "<C-c>", -- terminal-mode toggle for Codex window
59+
clear_input = "<M-BS>", -- clear the current terminal input line
5960
close = false, -- set a string (e.g. "<C-x>") to close Codex session
6061
nav = {
6162
left = "<C-h>", -- split windows only; set false to disable
@@ -90,6 +91,7 @@ require("codex").setup({
9091
- `:Codex!` force-opens and focuses the Codex terminal
9192
- `:CodexFocus` focuses the terminal (opens it if needed)
9293
- `:CodexClose` closes the active Codex terminal session
94+
- `:CodexClearInput` clears the active Codex terminal input line
9395
- `:CodexSend` sends selected lines with relative file path and line range
9496
- when a command range is provided, it takes precedence over visual marks
9597
- selection is linewise; visual columns are ignored (charwise/blockwise still
@@ -175,6 +177,7 @@ require("codex").setup({
175177
terminal = {
176178
keymaps = {
177179
toggle = "<C-c>",
180+
clear_input = "<M-BS>",
178181
close = "<C-x>",
179182
nav = {
180183
left = "<A-h>",
@@ -187,6 +190,7 @@ require("codex").setup({
187190
})
188191
```
189192

193+
`terminal.keymaps.clear_input` clears the current terminal input line.
190194
`terminal.keymaps.close` triggers an intentional Codex session close.
191195
`terminal.auto_close` controls whether provider windows auto-close only after
192196
the terminal process exits. `terminal.keymaps.nav` is applied only for split
@@ -198,6 +202,7 @@ navigation keymaps, or set individual directions to `false`.
198202
- `require("codex").send_selection()`
199203
- `require("codex").add_file(path)`
200204
- `require("codex").close()`
205+
- `require("codex").clear_input()`
201206
- `require("codex").send_command(slash_cmd)`
202207
- `require("codex").resume(opts)`
203208
- `require("codex").set_model()`

docs/architecture.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ Key types:
294294
| `codex.VsplitConfig` | class | Vertical split options (`side`, `size_pct`) |
295295
| `codex.HsplitConfig` | class | Horizontal split options (`side`, `size_pct`) |
296296
| `codex.FloatConfig` | class | Floating window options (size, border, title, title_pos) |
297-
| `codex.TerminalKeymapConfig` | class | Terminal-local keymaps (`toggle`, `close`) |
297+
| `codex.TerminalKeymapConfig` | class | Terminal-local keymaps (`toggle`, `clear_input`, `close`) |
298298
| `codex.KeymapConfig` | class | Keymap action table (`string` or `false` per action) |
299299
| `codex.ProviderName` | alias | Union of valid provider name strings |
300300
| `codex.LogLevel` | alias | Union of log level strings |
@@ -325,4 +325,4 @@ own internal handle structure; the core never inspects handle contents.
325325
`tests/contract/provider_contract_spec.lua` so the contract tests cover it.
326326
7. If the provider accepts options, add a default entry under
327327
`terminal.provider_opts` in `config.lua` and honor shared
328-
`terminal.keymaps` semantics for terminal-local toggle/close mappings.
328+
`terminal.keymaps` semantics for terminal-local toggle/clear/close mappings.

lua/codex/config.lua

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ M.defaults = {
3232
},
3333
keymaps = {
3434
toggle = "<C-c>",
35+
clear_input = "<M-BS>",
3536
close = false,
3637
nav = {
3738
left = "<C-h>",
@@ -68,10 +69,11 @@ local valid_providers = { auto = true, snacks = true, native = true }
6869
local valid_windows = { vsplit = true, hsplit = true, float = true }
6970
local valid_terminal_keymap_actions = {
7071
toggle = true,
72+
clear_input = true,
7173
close = true,
7274
nav = true,
7375
}
74-
local valid_terminal_keymap_action_list = "toggle, close, nav"
76+
local valid_terminal_keymap_action_list = "toggle, clear_input, close, nav"
7577
local valid_nav_keymap_actions = { left = true, down = true, up = true, right = true }
7678
local valid_nav_keymap_action_list = "left, down, up, right"
7779
local valid_keymap_actions = {

lua/codex/init.lua

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,22 @@ function M.send(text)
401401
})
402402
end
403403

404+
---@return boolean ok
405+
---@return string|nil err
406+
function M.clear_input()
407+
ensure_setup()
408+
local deps = get_deps()
409+
local session = deps.session_store.get_active()
410+
local provider = get_provider()
411+
412+
if not session_is_alive(session, provider) then
413+
return false, "no active Codex session"
414+
end
415+
416+
local clear_sequence = deps.vim.api.nvim_replace_termcodes("<C-c>", true, false, true)
417+
return provider.send(session.handle, clear_sequence)
418+
end
419+
404420
---@param slash_cmd string Slash command name with or without a leading `/`.
405421
---@return codex.SendResult ok True when command payload is sent.
406422
---@return string|nil err

lua/codex/nvim/commands.lua

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ function M.register()
7474
nargs = 0,
7575
})
7676

77+
vim.api.nvim_create_user_command("CodexClearInput", function()
78+
local codex = require("codex")
79+
codex.clear_input()
80+
end, {
81+
desc = "Clear the active Codex terminal input line",
82+
nargs = 0,
83+
})
84+
7785
---@param opts codex.UserCommandOpts
7886
vim.api.nvim_create_user_command("CodexSend", function(opts)
7987
local codex = require("codex")

lua/codex/providers/native.lua

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ end
153153
local function set_terminal_keymaps(bufnr, keymaps, window_type)
154154
local maps = vim.tbl_deep_extend("force", {
155155
toggle = "<C-c>",
156+
clear_input = "<M-BS>",
156157
close = false,
157158
nav = {
158159
left = "<C-h>",
@@ -173,6 +174,17 @@ local function set_terminal_keymaps(bufnr, keymaps, window_type)
173174
})
174175
end
175176

177+
if maps.clear_input then
178+
vim.keymap.set("t", maps.clear_input, function()
179+
require("codex").clear_input()
180+
end, {
181+
buffer = bufnr,
182+
silent = true,
183+
nowait = true,
184+
desc = "Codex: Clear input",
185+
})
186+
end
187+
176188
if maps.close then
177189
vim.keymap.set("t", maps.close, function()
178190
vim.schedule(function()

lua/codex/providers/snacks.lua

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ end
6464
local function set_terminal_keymaps(bufnr, keymaps, window_type)
6565
local maps = vim.tbl_deep_extend("force", {
6666
toggle = "<C-c>",
67+
clear_input = "<M-BS>",
6768
close = false,
6869
nav = {
6970
left = "<C-h>",
@@ -84,6 +85,17 @@ local function set_terminal_keymaps(bufnr, keymaps, window_type)
8485
})
8586
end
8687

88+
if maps.clear_input then
89+
vim.keymap.set("t", maps.clear_input, function()
90+
require("codex").clear_input()
91+
end, {
92+
buffer = bufnr,
93+
silent = true,
94+
nowait = true,
95+
desc = "Codex: Clear input",
96+
})
97+
end
98+
8799
if maps.close then
88100
vim.keymap.set("t", maps.close, function()
89101
vim.schedule(function()

lua/codex/types.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444

4545
---@class codex.TerminalKeymapConfig
4646
---@field toggle string|false
47+
---@field clear_input string|false
4748
---@field close string|false
4849
---@field nav codex.NavKeymapConfig|false
4950

tests/unit/commands_spec.lua

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ describe("codex.nvim command registration", function()
3030
assert.is_not_nil(registered.Codex)
3131
assert.is_not_nil(registered.CodexFocus)
3232
assert.is_not_nil(registered.CodexClose)
33+
assert.is_not_nil(registered.CodexClearInput)
3334
assert.is_not_nil(registered.CodexSend)
3435
assert.is_not_nil(registered.CodexAdd)
3536
assert.is_not_nil(registered.CodexResume)
@@ -56,6 +57,12 @@ describe("codex.nvim command registration", function()
5657
assert.equals("Close the active Codex terminal session", registered.CodexClose.opts.desc)
5758
assert.equals(0, registered.CodexClose.opts.nargs)
5859

60+
assert.equals(
61+
"Clear the active Codex terminal input line",
62+
registered.CodexClearInput.opts.desc
63+
)
64+
assert.equals(0, registered.CodexClearInput.opts.nargs)
65+
5966
assert.equals(
6067
"Send visual selection to Codex with file path and line range",
6168
registered.CodexSend.opts.desc
@@ -174,6 +181,23 @@ describe("codex.nvim command registration", function()
174181
end)
175182
end)
176183

184+
it("dispatches :CodexClearInput to clear_input", function()
185+
with_stubbed_command_registration(function(registered)
186+
local clear_input_calls = 0
187+
188+
package.loaded["codex"] = {
189+
clear_input = function()
190+
clear_input_calls = clear_input_calls + 1
191+
end,
192+
}
193+
194+
require("codex.nvim.commands").register()
195+
registered.CodexClearInput.callback()
196+
197+
assert.equals(1, clear_input_calls)
198+
end)
199+
end)
200+
177201
it("dispatches :CodexSend with range options", function()
178202
with_stubbed_command_registration(function(registered)
179203
local calls = {}

tests/unit/config_spec.lua

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ describe("codex.config", function()
3030
assert.equals(50, config.defaults.terminal.startup.retry_interval_ms)
3131
assert.equals(400, config.defaults.terminal.startup.grace_ms)
3232
assert.equals("<C-c>", config.defaults.terminal.keymaps.toggle)
33+
assert.equals("<M-BS>", config.defaults.terminal.keymaps.clear_input)
3334
assert.is_false(config.defaults.terminal.keymaps.close)
3435
assert.equals("<C-h>", config.defaults.terminal.keymaps.nav.left)
3536
assert.equals("<C-j>", config.defaults.terminal.keymaps.nav.down)
@@ -78,6 +79,7 @@ describe("codex.config", function()
7879
assert.equals("bottom", cfg.terminal.hsplit.side)
7980
assert.equals(50, cfg.terminal.hsplit.size_pct)
8081
assert.equals("<C-c>", cfg.terminal.keymaps.toggle)
82+
assert.equals("<M-BS>", cfg.terminal.keymaps.clear_input)
8183
assert.equals("<C-d>", cfg.terminal.keymaps.close)
8284
assert.equals("<C-h>", cfg.terminal.keymaps.nav.left)
8385
assert.equals("<C-j>", cfg.terminal.keymaps.nav.down)
@@ -252,15 +254,18 @@ describe("codex.config", function()
252254
end)
253255

254256
it("rejects unknown terminal keymap actions", function()
255-
assert.has_error(function()
256-
config.apply({
257-
terminal = {
258-
keymaps = {
259-
hide = "<C-x>",
257+
assert.has_error(
258+
function()
259+
config.apply({
260+
terminal = {
261+
keymaps = {
262+
hide = "<C-x>",
263+
},
260264
},
261-
},
262-
})
263-
end, 'codex: invalid terminal.keymaps action "hide", expected one of: toggle, close, nav')
265+
})
266+
end,
267+
'codex: invalid terminal.keymaps action "hide", expected one of: toggle, clear_input, close, nav'
268+
)
264269
end)
265270

266271
it("rejects unknown terminal nav keymap actions", function()

0 commit comments

Comments
 (0)